api.js 7.57 KB
import dataUtils from './data-utils.js'
import { HmacSHA256, MD5 } from '../vendors/crypto';
import { stringify } from '../vendors/query-stringify';

 //获取加签的秘钥
export const verify = {
  verifyMethod: 'resources.simple.pice',
  updateVerify() {
    return api.get({ // eslint-disable-line
      data: {
        method: this.verifyMethod
      }
    }).then(result => {
      if (result && result.code === 200 && result.data && result.data.sk) {
        wx.setStorageSync('verifyKey', result.data.sk);
      }

      return result;
    });
  },

  getVerifyKey() {
    const self = this;
    let maxTryTimes = 3;

    function update() {
      return self.updateVerify().then(result => {
        if (result && result.code === 200 && result.data && result.data.sk) {
          return result.data.sk;
        } else if (maxTryTimes) {
          maxTryTimes--;

          return update();
        } else {
          return '';
        }
      });
    }

    return update();
  },
  async get() {
    const verifyKey = dataUtils.getGlobalDataByKey('verifyKey');

    if (!verifyKey) {
      await this.getVerifyKey();
    }

    return verifyKey || '';
    
  }
}
const createBody = (body) => {
  let newBody = api.addParams(body);
  return newBody;
}
const sign = async(data, encode = false) => {
  const verifyKey = await verify.get();

  if (!verifyKey) {
    return '';
  }

  data = stringifyParam(data, encode)

  return HmacSHA256(data, verifyKey).toString();


  
  // if (data.method === verifyCutMethod) {
  //   verifyKey = 'bc330db80e80fa1f0204e7bbf83063f2'
  // }
}
const stringifyParam = (data, encode = false) => {
  data = stringify(data, {
    encode: encode
  });
  return data
}
export const computeSecret = (data, url, encode = false) => {
  let newData = {
    private_key: dataUtils.getConfig().apiParams.private_key
  };

  Object.keys(data).sort().forEach(key => {
    newData[key] = String(data[key]).trim();
  });

  newData.client_secret = MD5(stringify(newData, {
    encode: encode
  })).toString();
  delete newData.private_key;

  if (url) {
    let body = createBody(data);
    let queryStrigPair = stringifyParam(body, true);;

    url = url.indexOf('?') >= 0 ? url + '&' + queryStrigPair : url + '?' + queryStrigPair;
    newData.url = url
  }

  return newData;
}
const fetch = (params = {}) => {
  return new Promise((resolve, reject) => {
      wx.request({
        ...params,
        success(res) {
          resolve(res)
        },
        fail(err) {
          reject(err)
        }
      })
  })
}
const api = {
  async request(params ={}) {

      // 公有参数
      params.data = this.addParams(params.data);
      params = this.addSessionKey(params);

      // client_secret
      params.data = computeSecret(params.data);

      // 接口验签
      if (!params.header['x-yoho-verify'] && params.data.method !== verify.verifyMethod) {
        params.header['x-yoho-verify'] = await sign(params.data);
      }

      return fetch(params).then(result => {
        if (result.statusCode === 200) {
          const resultData = result && result.data || {};

          delete result.data;
          resultData.result = result;

          if (resultData.code === 508) { // 验签未通过
            verify.getVerifyKey();

          }

          if (resultData.code === params.code && params.code) {
            return resultData.data || {};
          }

          return resultData;
        } else if (result.statusCode === 401) { // 用户信息校验失败
          dataUtils.clearUserSession();
        } else {
          console.error('api statusCode:', result.statusCode);
          return result && result.data || {};
        }
      }).catch(err => {
        console.error(err);
        return err
      });
    
  },
  addSessionKey(params ={}) {
    let uid = params.data.uid || dataUtils.getUid();
    let sessionKey = dataUtils.getGlobalDataByKey('sessionkey') || '';

    // if (uid && sessionKey) {
      params.data.session_key = sessionKey;
      params.data.uid = uid;
      params.header.Cookies = `JSESSIONID=${sessionKey}`;
    // }

    return params;
  },
  addSysInfo() {
    let sysInfoParams = {}
    let res = dataUtils.getGlobalDataByKey('systemInfo')
    sysInfoParams.screen_size = res.windowWidth + 'x' + res.windowHeight;
    sysInfoParams.os_version = res.version;
    return sysInfoParams
  },
  addParams(params = {}) {
    let sysParams = this.addSysInfo()
    return { ...dataUtils.getConfig().apiParams, ...sysParams, udid: dataUtils.getGlobalDataByKey('udid'), ...params}
  },
  get(params ={}) {
    // 默认值
    let requestParams = {
      data: {},
      header: {},
      dataType: 'json', 
      ...params,
      url: dataUtils.getConfig().domains[params.api || 'api'] + (params.url || '')};

    // 构造好参数再请求
    return this.request(requestParams);
  },
  post(params ={}) {
    // 默认值
    let requestParams = {
      method: 'post',
      data: {},
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      dataType: 'json', 
      ...params,
      url: dataUtils.getConfig().domains[params.api || 'api'] + (params.url || '')
      };

    // 构造好参数再请求
    return this.request(requestParams);
  },
  uploadLog(params = {}) {
    let sid = dataUtils.getGlobalDataByKey('sid') || ''
    // 默认值
    let requestParams = {
      method: 'post',
      data: { '_mlogs': JSON.stringify(params) },
      header: {
        'content-type': 'application/x-www-form-urlencoded',
        'x-yoho-sid': MD5(sid),
      },
      url: dataUtils.getConfig().domains[params.api || 'yasApi'] + (params.url || '')
    };
    return fetch(requestParams)
  },
  appReport(params = {}) {
    let sid = dataUtils.getGlobalDataByKey('sid') || ''
    // 默认值
    let requestParams = {
      method: 'post',
      data: JSON.stringify(params),
      header: {
        'content-type': "application/json",
        'x-yoho-sid': MD5(sid),
      },
      url: dataUtils.getConfig().domains[params.api || 'app_report_host'] + (params.url || '')
    };
    return fetch(requestParams)
  },
  async uploadFile(filePath, index = 0) {
    let params = {
      data: {
        project: 'evidenceImages'
      },
      header: {
        'content-type': "multipart/form-data",
        'HTTP_REFERER': 'admin.yohobuy.com',
        'Host': 'upload.static.yohobuy.com'
      }
    }
    // 公有参数
    params.data = this.addParams(params.data);
    params = this.addSessionKey(params);
    
    // client_secret
    params.data = computeSecret(params.data);

    params.header.Cookie = params.header.Cookies
    // 接口验签
    params.header['x-yoho-verify'] = await sign(params.data);
    return new Promise(function (resolve, reject) {
      wx.uploadFile({
        url: 'https://upload.static.yohobuy.com/', //仅为示例,非真实的接口地址
        filePath: filePath,
        name: 'fileData',
        formData: params.data,
        success(res) {
          const data = res.data;
          const dataObj = JSON.parse(data);
          if (dataObj && dataObj.code === 200) {
            console.log('uploadFile.success: ', index);
            resolve({
              ...dataObj.data,
              index
            });
          } else {
            reject(dataObj, index);
          }
        },
        fail(error) {
          reject(error, index);
        }
      })
    });
  }
}
export default api;