const needle = require('needle') const moment = require('moment') const {Class} = require("./Class"); const {RequestType} = require('./RequestType') const {SignUtil} = require('./SignUtil') const {BaseRequest} = require('../request/BaseRequest') const HEADERS = {'Accept-Encoding': 'identity'} const getHeaders = function (headers) { if (!headers) { return HEADERS } for (const key in HEADERS) { headers[key] = HEADERS[key]; } return headers } const OpenClient = Class.create({ /** * 初始化客户端 * @param appId 应用ID * @param privateKey 应用私钥,2048位,PKCS8 * @param url 请求url */ init: function (appId, privateKey, url) { this.appId = appId; this.privateKey = privateKey; this.url = url; }, /** * 发送请求 * @param request 请求类 * @param callback 回调函数,参数json */ execute: function (request, callback) { this.executeToken(request,null, null, callback) }, executeUserToken: function (request, userToken, callback) { this.executeToken(request, userToken, null, callback) }, executeAppToken: function (request, appToken, callback) { this.executeToken(request, null, appToken, callback) }, /** * 发送请求 * @param request 请求类 * @param userToken 用户token * @param appToken 应用token * @param callback 回调函数,参数json */ executeToken: function (request, userToken, appToken, callback) { if (!(request instanceof BaseRequest)) { throw 'request类未继承BaseRequest' } const requestType = request.getRequestType(); if (request.files && request.files.length > 0) { this._postFile(request, userToken, appToken, callback); } else { switch (requestType) { case RequestType.GET: this._get(request, userToken, appToken, callback); break case RequestType.POST_FORM: this._form(request, 'POST', userToken, appToken, callback); break case RequestType.POST_JSON: this._json(request, 'POST', userToken, appToken, callback); break case RequestType.POST_FILE: this._postFile(request, userToken, appToken, callback); break case RequestType.PUT: this._json(request, 'PUT', userToken, appToken, callback); break case RequestType.DELETE: this._json(request, 'DELETE', userToken, appToken, callback); break default :{ throw 'request.getRequestType()类型不正确' } } } }, _get: function(request, userToken, appToken, callback) { const allParams = this._buildParams(request, userToken, appToken) const that = this // needle.request(method, url, data[, options][, callback]) needle.request('GET',this.url, allParams, { headers: getHeaders() }, function(error, response) { callback(that._parseResponse(error, response, request)) }); }, _form: function (request, method, userToken, appToken, callback) { const allParams = this._buildParams(request, userToken, appToken) const that = this needle.request(method, this.url, allParams, { headers: getHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }) }, function(error, response) { callback(that._parseResponse(error, response, request)) }); }, _json: function (request, method, userToken, appToken, callback) { const allParams = this._buildParams(request, userToken, appToken) const that = this needle.request(method, this.url, allParams, { headers: getHeaders(), json: true }, function(error, response) { callback(that._parseResponse(error, response, request)) }); }, _postFile: function (request, userToken, appToken, callback) { const allParams = this._buildParams(request, userToken, appToken) const files = request.files; files.forEach(row => { // 设置成{ file: row.path, content_type: 'application/octet-stream' }格式 // needle会认为是上传文件 allParams[row.name] = { file: row.path, content_type: 'application/octet-stream' } }) const that = this needle.request('POST',this.url, allParams, { headers: getHeaders(), multipart: true }, function(error, response) { callback(that._parseResponse(error, response, request)) }); }, _parseResponse: function (error, response, request) { if (!error) { return request.parseResponse(response.body) } else { throw '请求异常:' + error } }, _buildParams: function (request, userToken, appToken) { const allParams = { 'app_id': this.appId, 'method': request.getMethod(), 'charset': 'UTF-8', 'sign_type': 'RSA2', 'timestamp': moment().valueOf(), 'version': request.getVersion(), 'sdk_version': request.getSdkVersion() } allParams['biz_content'] = JSON.stringify(request.bizModel) allParams['params_content'] = JSON.stringify(request.paramsModel) if (userToken) { allParams['user_access_token'] = userToken } if (appToken) { allParams['app_auth_token'] = appToken } // 创建签名 const sign = SignUtil.createSign(allParams, this.privateKey, 'RSA2') allParams.sign = sign return allParams; } }) module.exports = OpenClient