From 764d4924492f36b4a1072828810f6d04a290c8cd Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 00:30:43 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=96=B0=E5=A2=9Enodejs-axios=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs-axios/common/OpenClient.js | 183 ++++++++++++++++++ .../sdk-nodejs-axios/common/RequestType.js | 6 + sop-sdk/sdk-nodejs-axios/common/SignUtil.js | 88 +++++++++ sop-sdk/sdk-nodejs-axios/package.json | 21 ++ .../sdk-nodejs-axios/request/BaseRequest.js | 78 ++++++++ 5 files changed, 376 insertions(+) create mode 100644 sop-sdk/sdk-nodejs-axios/common/OpenClient.js create mode 100644 sop-sdk/sdk-nodejs-axios/common/RequestType.js create mode 100644 sop-sdk/sdk-nodejs-axios/common/SignUtil.js create mode 100644 sop-sdk/sdk-nodejs-axios/package.json create mode 100644 sop-sdk/sdk-nodejs-axios/request/BaseRequest.js diff --git a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js new file mode 100644 index 00000000..d242a096 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js @@ -0,0 +1,183 @@ +const axios = require('axios'); +const formData = require('form-data'); +const moment = require('moment'); +const qs = require('qs'); + +const {RequestType} = require('./RequestType'); +const {SignUtil} = require('./SignUtil'); +const {BaseRequest} = require('../request/BaseRequest'); + +const HEADERS = {'Accept-Encoding': 'identity'}; + +const getHeaders = (headers = {}) => { + return Object.assign({}, headers, HEADERS); +}; + +const parseResponse = (error, response, request) => { + if (!error && response.status === 200) { + return request.parseResponse(response.data); + } else { + return { // 重新封装请求异常回调,以防中断 + msg: '请求异常', + code: '502', + sub_msg: `${error}`, + sub_code: 'isv.invalid-server' + }; + } +}; + +const buildParams = (instance, request, token) => { + const {appId, privateKey} = instance; + const allParams = { + 'app_id': appId, + 'method': request.getMethod(), + 'charset': 'UTF-8', + 'sign_type': 'RSA2', + 'timestamp': moment().format('YYYY-MM-DD HH:mm:ss'), + 'version': request.getVersion(), + 'biz_content': JSON.stringify(request.bizModel) + }; + + if (token) { + allParams['app_auth_token'] = token; + } + // 创建签名 + allParams.sign = SignUtil.createSign(allParams, privateKey, 'RSA2'); + return allParams; +}; + +const executeRequest = async (instance = {}, request, token, callback, {headers}) => { + const params = buildParams(instance, request, token); + const {url} = instance; + const options = { + url, + method: 'POST', + params: undefined, + data: undefined + }; + headers = getHeaders(headers); + const requestType = request.getRequestType(); + switch (requestType) { + case RequestType.GET: { + options.method = 'GET'; + options.params = params; + } + break; + case RequestType.POST_FORM: { + headers = Object.assign(headers, { + 'Content-Type': 'application/x-www-form-urlencoded' + }); + options.data = qs.stringify(params); + } + break; + case RequestType.POST_JSON: { + options.data = params; + } + break; + case RequestType.POST_FILE: { + const formData = new formData(); + (request.files || []).forEach(({name, path}) => { + formData.append(name, path, { + contentType: 'application/octet-stream' + }); + }); + Object.keys(params).forEach(key => { + const value = params[key]; + if (!(typeof key === 'undefined' || typeof value === 'undefined')) { + formData.append(key, params[key]); + } + }); + options.data = formData; + } + break; + default: { + callback(parseResponse(new Error('request.getRequestType()类型不正确'), undefined, request)); + return; + } + } + try { + options['headers'] = headers; + const response = await axios.request(options); + callback(parseResponse(undefined, response, request)); + } catch (error) { + callback(parseResponse(error, undefined, request)); + } +}; + +module.exports = class OpenClient { + /** + * 初始化客户端 + * @param appId 应用ID + * @param privateKey 应用私钥,2048位,PKCS8 + * @param url 请求url + */ + constructor(appId, privateKey, url) { + this.appId = appId; + this.privateKey = privateKey; + this.url = url; + } + + /** + * 发送请求 + * @param request 请求类 + * @param callback 回调函数,参数json(undefined则使用executeSync) + * @param options 自定义参数,如headers + */ + execute(request, callback, options) { + if (typeof callback == 'function') { + return this.executeToken(request, null, callback, options); + } else { + return this.executeSync(request, options); + } + } + + /** + * 发送同步请求 + * @param request 请求类 + * @param options 自定义参数,如headers + * */ + executeSync(request, options) { + return new Promise((resolve) => { + const _ = this.execute(request, res => { + resolve(res); + }, options); + }); + } + + /** + * 发送请求 + * @param request 请求类 + * @param token token + * @param callback 回调函数,参数json(undefined则使用executeTokenSync) + * @param options 自定义参数,如headers + */ + async executeToken(request, token, callback, options) { + if (!(request instanceof BaseRequest)) { + throw 'request类未继承BaseRequest'; + } + if (typeof callback == 'function') { + const files = request.files; + if (files && files.length > 0) { + request.setForceRequestType(RequestType.POST_FILE); + } + return await executeRequest(this, request, token, callback, options); + } else { + return this.executeTokenSync(request, token); + } + } + + /** + * 发送同步请求 + * @param request 请求类 + * @param token token + * @param options 自定义参数,如headers + */ + executeTokenSync(request, token, options) { + return new Promise((resolve) => { + const _ = this.executeToken(request, token, res => { + resolve(res); + }, options); + }); + } + +}; \ No newline at end of file diff --git a/sop-sdk/sdk-nodejs-axios/common/RequestType.js b/sop-sdk/sdk-nodejs-axios/common/RequestType.js new file mode 100644 index 00000000..717d99f5 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/common/RequestType.js @@ -0,0 +1,6 @@ +exports.RequestType = { + GET: 'GET', + POST_FORM: 'POST_FORM', + POST_JSON: 'POST_JSON', + POST_FILE: 'POST_FILE' +}; diff --git a/sop-sdk/sdk-nodejs-axios/common/SignUtil.js b/sop-sdk/sdk-nodejs-axios/common/SignUtil.js new file mode 100644 index 00000000..453b3dbe --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/common/SignUtil.js @@ -0,0 +1,88 @@ +const {KJUR, hextob64} = require('jsrsasign'); + +const HashMap = { + SHA256withRSA: 'SHA256withRSA', + SHA1withRSA: 'SHA1withRSA' +}; + +const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n'; +const PEM_END = '\n-----END PRIVATE KEY-----'; + +/** + * rsa签名参考:https://www.jianshu.com/p/145eab95322c + */ +exports.SignUtil = { + /** + * 创建签名 + * @param params 请求参数 + * @param privateKey 私钥,PKCS8 + * @param signType 签名类型,RSA,RSA2 + * @returns 返回签名内容 + */ + createSign(params, privateKey, signType) { + const content = this.getSignContent(params); + return this.sign(content, privateKey, signType); + }, + sign: function (content, privateKey, signType) { + if (signType.toUpperCase() === 'RSA') { + return this.rsaSign(content, privateKey, HashMap.SHA1withRSA); + } else if (signType.toUpperCase() === 'RSA2') { + return this.rsaSign(content, privateKey, HashMap.SHA256withRSA); + } else { + throw 'signType错误'; + } + }, + /** + * rsa签名 + * @param content 签名内容 + * @param privateKey 私钥 + * @param hash hash算法,SHA256withRSA,SHA1withRSA + * @returns 返回签名字符串,base64 + */ + rsaSign: function (content, privateKey, hash) { + privateKey = this._formatKey(privateKey); + // 创建 Signature 对象 + const signature = new KJUR.crypto.Signature({ + alg: hash, + //!这里指定 私钥 pem! + prvkeypem: privateKey + }); + signature.updateString(content); + const signData = signature.sign(); + // 将内容转成base64 + return hextob64(signData); + }, + _formatKey: function (key) { + if (!key.startsWith(PEM_BEGIN)) { + key = PEM_BEGIN + key; + } + if (!key.endsWith(PEM_END)) { + key = key + PEM_END; + } + return key; + }, + /** + * 获取签名内容 + * @param params 请求参数 + * @returns {string} + */ + getSignContent: function (params) { + const paramNames = []; + for (const key in params) { + paramNames.push(key); + } + + paramNames.sort(); + + const paramNameValue = []; + + for (let i = 0, len = paramNames.length; i < len; i++) { + const paramName = paramNames[i]; + const val = params[paramName]; + if (paramName && val) { + paramNameValue.push(`${paramName}=${val}`); + } + } + return paramNameValue.join('&'); + } +}; diff --git a/sop-sdk/sdk-nodejs-axios/package.json b/sop-sdk/sdk-nodejs-axios/package.json new file mode 100644 index 00000000..88232a74 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/package.json @@ -0,0 +1,21 @@ +{ + "name": "sdk-nodejs", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.21.1", + "form-data": "^4.0.0", + "isarray": "^2.0.5", + "isobject": "^4.0.0", + "jsrsasign": "^8.0.19", + "moment": "^2.27.0", + "qs": "^6.10.1" + } +} diff --git a/sop-sdk/sdk-nodejs-axios/request/BaseRequest.js b/sop-sdk/sdk-nodejs-axios/request/BaseRequest.js new file mode 100644 index 00000000..a3b5b641 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/request/BaseRequest.js @@ -0,0 +1,78 @@ +const isArray = require('isarray'); +/** + * 请求类父类 + */ +exports.BaseRequest = class BaseRequest { + constructor() { + this.bizModel = {}; + + this.files = undefined; + + // 用于文件上传时强制转换成POST_FILE请求 + this.__forceRequestType__ = undefined; + } + + setBizModel(biz = {}) { + this.bizModel = biz; + return this; + } + + setFiles(files) { + this.files = files; + return this; + } + + addFile({name, path}) { + if (name && path) { + if (!isArray(this.files)) { + this.files = []; + } + this.files.push({name, path}); + } + return this; + } + + /** + * 返回接口名称 + */ + getMethod() { + throw `未实现BaseRequest类getMethod()方法`; + } + + /** + * 返回版本号 + */ + getVersion() { + throw '未实现BaseRequest类getVersion()方法'; + } + + /** + * 返回请求类型,使用RequestType.js + */ + getRequestType() { + throw '未实现BaseRequest类getRequestType()方法'; + } + + setForceRequestType(type) { + this.__forceRequestType__ = type; + return this; + } + + getRealRequestType() { + return this.__forceRequestType__ || this.getRequestType(); + } + + /** + * 解析返回结果,子类可以覆盖实现 + * @param responseData 服务器返回内容 + * @returns 返回结果 + */ + parseResponse(responseData) { + let data = responseData['error_response']; + if (!data) { + const dataNodeName = this.getMethod().replace(/\./g, '_') + '_response'; + data = responseData[dataNodeName]; + } + return data; + } +}; \ No newline at end of file From ccca3c26ee62049209a3af2f2b109cd4c0024519 Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 10:21:38 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=AE=8C=E5=96=84sdk-nodejs-axios=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs-axios/.gitignore | 16 +++++ sop-sdk/sdk-nodejs-axios/common/OpenClient.js | 59 ++++++++++++++----- .../sdk-nodejs-axios/common/RequestType.js | 2 +- sop-sdk/sdk-nodejs-axios/common/SignUtil.js | 2 +- sop-sdk/sdk-nodejs-axios/main.js | 44 ++++++++++++++ sop-sdk/sdk-nodejs-axios/readme.md | 10 ++++ .../request/StoryGetRequest.js | 19 ++++++ 7 files changed, 135 insertions(+), 17 deletions(-) create mode 100644 sop-sdk/sdk-nodejs-axios/.gitignore create mode 100644 sop-sdk/sdk-nodejs-axios/main.js create mode 100644 sop-sdk/sdk-nodejs-axios/readme.md create mode 100644 sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js diff --git a/sop-sdk/sdk-nodejs-axios/.gitignore b/sop-sdk/sdk-nodejs-axios/.gitignore new file mode 100644 index 00000000..9ad28d23 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +package-lock.json +tests/**/coverage/ + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js index d242a096..0dfd5c0a 100644 --- a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js +++ b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js @@ -1,11 +1,12 @@ const axios = require('axios'); -const formData = require('form-data'); const moment = require('moment'); const qs = require('qs'); -const {RequestType} = require('./RequestType'); -const {SignUtil} = require('./SignUtil'); -const {BaseRequest} = require('../request/BaseRequest'); +const RequestType = require('./RequestType'); +const SignUtil = require('./SignUtil'); +const BaseRequest = require('./BaseRequest'); + +const IS_RUN_IN_BROWSER = this === window; const HEADERS = {'Accept-Encoding': 'identity'}; @@ -56,7 +57,7 @@ const executeRequest = async (instance = {}, request, token, callback, {headers} data: undefined }; headers = getHeaders(headers); - const requestType = request.getRequestType(); + const requestType = request.getRealRequestType(); switch (requestType) { case RequestType.GET: { options.method = 'GET'; @@ -75,18 +76,31 @@ const executeRequest = async (instance = {}, request, token, callback, {headers} } break; case RequestType.POST_FILE: { - const formData = new formData(); - (request.files || []).forEach(({name, path}) => { - formData.append(name, path, { - contentType: 'application/octet-stream' - }); - }); Object.keys(params).forEach(key => { const value = params[key]; if (!(typeof key === 'undefined' || typeof value === 'undefined')) { formData.append(key, params[key]); } }); + let formData; + if (IS_RUN_IN_BROWSER) { + formData = new window.FormData() + (request.files || []).forEach(({name, path}) => { + formData.append(name, path, { + contentType: 'application/octet-stream' + }); + }); + } else { + const fs = require('fs'); + const fd = require('form-data'); + formData = new fd(); + (request.files || []).forEach(({name, path}) => { + formData.append(name, fs.createReadStream(path), { + contentType: 'application/octet-stream' + }); + }); + headers = Object.assign(headers, formData.getHeaders()); + } options.data = formData; } break; @@ -112,9 +126,24 @@ module.exports = class OpenClient { * @param url 请求url */ constructor(appId, privateKey, url) { - this.appId = appId; - this.privateKey = privateKey; - this.url = url; + this.appId = appId || ''; + this.privateKey = privateKey || ''; + this.url = url || ''; + } + + setAppId(appId) { + this.appId = appId || ''; + return this; + } + + setPrivateKey(privateKey) { + this.privateKey = privateKey || ''; + return this; + } + + setUrl(url) { + this.url = url || ''; + return this; } /** @@ -180,4 +209,4 @@ module.exports = class OpenClient { }); } -}; \ No newline at end of file +}; diff --git a/sop-sdk/sdk-nodejs-axios/common/RequestType.js b/sop-sdk/sdk-nodejs-axios/common/RequestType.js index 717d99f5..f745548d 100644 --- a/sop-sdk/sdk-nodejs-axios/common/RequestType.js +++ b/sop-sdk/sdk-nodejs-axios/common/RequestType.js @@ -1,4 +1,4 @@ -exports.RequestType = { +module.exports = { GET: 'GET', POST_FORM: 'POST_FORM', POST_JSON: 'POST_JSON', diff --git a/sop-sdk/sdk-nodejs-axios/common/SignUtil.js b/sop-sdk/sdk-nodejs-axios/common/SignUtil.js index 453b3dbe..98e2ceb6 100644 --- a/sop-sdk/sdk-nodejs-axios/common/SignUtil.js +++ b/sop-sdk/sdk-nodejs-axios/common/SignUtil.js @@ -11,7 +11,7 @@ const PEM_END = '\n-----END PRIVATE KEY-----'; /** * rsa签名参考:https://www.jianshu.com/p/145eab95322c */ -exports.SignUtil = { +module.exports = { /** * 创建签名 * @param params 请求参数 diff --git a/sop-sdk/sdk-nodejs-axios/main.js b/sop-sdk/sdk-nodejs-axios/main.js new file mode 100644 index 00000000..82fdac2f --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/main.js @@ -0,0 +1,44 @@ +const OpenClient = require('./common/OpenClient'); + +const StoryGetRequest = require('./request/StoryGetRequest'); + +// 应用ID +const appId = '2019032617262200001'; +// 应用私钥,2048位,PKCS8 +const privateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ='; +// 接口url +const url = 'http://localhost:8081'; + +// 创建客户端 +const openClient = new OpenClient().setUrl(url).setAppId(appId).setPrivateKey(privateKey); + +(async () => { + // 创建请求 + const request = new StoryGetRequest(); + + // 设置业务参数 + const bizModel = { + id: 111, + name: 'jim' + }; + request.setBizModel(bizModel); + + // 添加上传文件 + // 批量添加 + const files = [ + // name: 表单名称,path:文件全路径 + {name: 'file1', path: `${__dirname}/aa.txt`}, + {name: 'file2', path: `${__dirname}/bb.txt`} + ]; + request.setFiles(files); + // 单个添加 + request.addFile('file3', `${__dirname}/package.json`); + + const data = await openClient.executeSync(request); + // 成功 + if (!data.sub_code) { + console.log('成功', data); + } else { + console.error('失败', data); + } +})(); diff --git a/sop-sdk/sdk-nodejs-axios/readme.md b/sop-sdk/sdk-nodejs-axios/readme.md new file mode 100644 index 00000000..79b852e5 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/readme.md @@ -0,0 +1,10 @@ +- 执行`npm install --registry=https://registry.npm.taobao.org` + +- 执行`node main.js`进行测试 + +## 封装步骤 + +1. 新建request类,继承BaseRequest,参考`StoryGetRequest.js` + +2. 调用接口,参考`main.js` + diff --git a/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js b/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js new file mode 100644 index 00000000..243084a7 --- /dev/null +++ b/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js @@ -0,0 +1,19 @@ +const BaseRequest = require('../common/BaseRequest'); +const RequestType = require('../common/RequestType'); + +/** + * 创建一个请求类,继承BaseRequest,重写三个函数 + */ +module.exports = class StoryGetRequest extends BaseRequest { + getMethod() { + return 'story.get'; + } + + getVersion() { + return '1.0'; + } + + getRequestType() { + return RequestType.GET; + } +}; From f09e00ddd7eee920fd07ad804fdd726f0eb5a895 Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 10:21:52 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=AE=8C=E5=96=84sdk-nodejs-axios=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{request => common}/BaseRequest.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) rename sop-sdk/sdk-nodejs-axios/{request => common}/BaseRequest.js (82%) diff --git a/sop-sdk/sdk-nodejs-axios/request/BaseRequest.js b/sop-sdk/sdk-nodejs-axios/common/BaseRequest.js similarity index 82% rename from sop-sdk/sdk-nodejs-axios/request/BaseRequest.js rename to sop-sdk/sdk-nodejs-axios/common/BaseRequest.js index a3b5b641..255f8870 100644 --- a/sop-sdk/sdk-nodejs-axios/request/BaseRequest.js +++ b/sop-sdk/sdk-nodejs-axios/common/BaseRequest.js @@ -2,7 +2,7 @@ const isArray = require('isarray'); /** * 请求类父类 */ -exports.BaseRequest = class BaseRequest { +module.exports = class BaseRequest { constructor() { this.bizModel = {}; @@ -10,6 +10,21 @@ exports.BaseRequest = class BaseRequest { // 用于文件上传时强制转换成POST_FILE请求 this.__forceRequestType__ = undefined; + + this.checkOverride(); + } + + /** + * 校验子类是否已重写相关方法 + * */ + checkOverride() { + try { + this.getMethod(); + this.getVersion(); + this.getRequestType(); + } catch (error) { + throw error; + } } setBizModel(biz = {}) { @@ -22,7 +37,7 @@ exports.BaseRequest = class BaseRequest { return this; } - addFile({name, path}) { + addFile(name, path) { if (name && path) { if (!isArray(this.files)) { this.files = []; @@ -75,4 +90,4 @@ exports.BaseRequest = class BaseRequest { } return data; } -}; \ No newline at end of file +}; From 2d6370ba1b0165bf300190e86b0de2073d016a4c Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 10:33:57 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E5=AE=8C=E5=96=84sdk-nodejs-axios=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs-axios/common/OpenClient.js | 33 ++++++++++--------- sop-sdk/sdk-nodejs-axios/main.js | 16 ++++----- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js index 0dfd5c0a..fe0d1820 100644 --- a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js +++ b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js @@ -6,7 +6,7 @@ const RequestType = require('./RequestType'); const SignUtil = require('./SignUtil'); const BaseRequest = require('./BaseRequest'); -const IS_RUN_IN_BROWSER = this === window; +const IS_RUN_IN_BROWSER = typeof window !== 'undefined' && this === window; const HEADERS = {'Accept-Encoding': 'identity'}; @@ -47,10 +47,11 @@ const buildParams = (instance, request, token) => { return allParams; }; -const executeRequest = async (instance = {}, request, token, callback, {headers}) => { +const executeRequest = async (instance = {}, request, token, callback, customOptions = {}) => { const params = buildParams(instance, request, token); const {url} = instance; - const options = { + let {headers} = customOptions; + const config = { url, method: 'POST', params: undefined, @@ -60,28 +61,22 @@ const executeRequest = async (instance = {}, request, token, callback, {headers} const requestType = request.getRealRequestType(); switch (requestType) { case RequestType.GET: { - options.method = 'GET'; - options.params = params; + config.method = 'GET'; + config.params = params; } break; case RequestType.POST_FORM: { headers = Object.assign(headers, { 'Content-Type': 'application/x-www-form-urlencoded' }); - options.data = qs.stringify(params); + config.data = qs.stringify(params); } break; case RequestType.POST_JSON: { - options.data = params; + config.data = params; } break; case RequestType.POST_FILE: { - Object.keys(params).forEach(key => { - const value = params[key]; - if (!(typeof key === 'undefined' || typeof value === 'undefined')) { - formData.append(key, params[key]); - } - }); let formData; if (IS_RUN_IN_BROWSER) { formData = new window.FormData() @@ -101,7 +96,13 @@ const executeRequest = async (instance = {}, request, token, callback, {headers} }); headers = Object.assign(headers, formData.getHeaders()); } - options.data = formData; + Object.keys(params).forEach(key => { + const value = params[key]; + if (!(typeof key === 'undefined' || typeof value === 'undefined')) { + formData.append(key, params[key]); + } + }); + config.data = formData; } break; default: { @@ -110,8 +111,8 @@ const executeRequest = async (instance = {}, request, token, callback, {headers} } } try { - options['headers'] = headers; - const response = await axios.request(options); + config['headers'] = headers; + const response = await axios.request(config); callback(parseResponse(undefined, response, request)); } catch (error) { callback(parseResponse(error, undefined, request)); diff --git a/sop-sdk/sdk-nodejs-axios/main.js b/sop-sdk/sdk-nodejs-axios/main.js index 82fdac2f..01a33c1f 100644 --- a/sop-sdk/sdk-nodejs-axios/main.js +++ b/sop-sdk/sdk-nodejs-axios/main.js @@ -25,14 +25,14 @@ const openClient = new OpenClient().setUrl(url).setAppId(appId).setPrivateKey(pr // 添加上传文件 // 批量添加 - const files = [ - // name: 表单名称,path:文件全路径 - {name: 'file1', path: `${__dirname}/aa.txt`}, - {name: 'file2', path: `${__dirname}/bb.txt`} - ]; - request.setFiles(files); - // 单个添加 - request.addFile('file3', `${__dirname}/package.json`); + // const files = [ + // // name: 表单名称,path:文件全路径 + // {name: 'file1', path: `${__dirname}/aa.txt`}, + // {name: 'file2', path: `${__dirname}/bb.txt`} + // ]; + // request.setFiles(files); + // // 单个添加 + // request.addFile('file3', `${__dirname}/package.json`); const data = await openClient.executeSync(request); // 成功 From c573a5118d038e5ae5ffc606dafab4c832829df6 Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 10:41:53 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E5=AE=8C=E5=96=84sdk-nodejs-axios=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs-axios/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sop-sdk/sdk-nodejs-axios/main.js b/sop-sdk/sdk-nodejs-axios/main.js index 01a33c1f..766285c4 100644 --- a/sop-sdk/sdk-nodejs-axios/main.js +++ b/sop-sdk/sdk-nodejs-axios/main.js @@ -27,8 +27,8 @@ const openClient = new OpenClient().setUrl(url).setAppId(appId).setPrivateKey(pr // 批量添加 // const files = [ // // name: 表单名称,path:文件全路径 - // {name: 'file1', path: `${__dirname}/aa.txt`}, - // {name: 'file2', path: `${__dirname}/bb.txt`} + // {name: 'file1', path: `${__dirname}/main.js`}, + // {name: 'file2', path: `${__dirname}/readme.md`} // ]; // request.setFiles(files); // // 单个添加 From fc82fab1cf1e33634aabe24e781ff097611b68d4 Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 14:10:46 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BD=BF=E7=94=A8es6+axios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs/aa.txt | 1 - sop-sdk/sdk-nodejs/bb.txt | 1 - sop-sdk/sdk-nodejs/common/Class.js | 124 -------- sop-sdk/sdk-nodejs/common/OpenClient.js | 289 ++++++++++-------- sop-sdk/sdk-nodejs/common/RequestType.js | 2 +- sop-sdk/sdk-nodejs/common/SignUtil.js | 25 +- sop-sdk/sdk-nodejs/main.js | 68 ++--- sop-sdk/sdk-nodejs/package.json | 7 +- sop-sdk/sdk-nodejs/request/BaseRequest.js | 48 --- sop-sdk/sdk-nodejs/request/StoryGetRequest.js | 25 +- sop-sdk/sdk-nodejs/testClass.js | 52 ---- 11 files changed, 209 insertions(+), 433 deletions(-) delete mode 100644 sop-sdk/sdk-nodejs/aa.txt delete mode 100644 sop-sdk/sdk-nodejs/bb.txt delete mode 100644 sop-sdk/sdk-nodejs/common/Class.js delete mode 100644 sop-sdk/sdk-nodejs/request/BaseRequest.js delete mode 100644 sop-sdk/sdk-nodejs/testClass.js diff --git a/sop-sdk/sdk-nodejs/aa.txt b/sop-sdk/sdk-nodejs/aa.txt deleted file mode 100644 index 524527cb..00000000 --- a/sop-sdk/sdk-nodejs/aa.txt +++ /dev/null @@ -1 +0,0 @@ -hello你好123 \ No newline at end of file diff --git a/sop-sdk/sdk-nodejs/bb.txt b/sop-sdk/sdk-nodejs/bb.txt deleted file mode 100644 index 85f8e329..00000000 --- a/sop-sdk/sdk-nodejs/bb.txt +++ /dev/null @@ -1 +0,0 @@ -文件bb的内容 \ No newline at end of file diff --git a/sop-sdk/sdk-nodejs/common/Class.js b/sop-sdk/sdk-nodejs/common/Class.js deleted file mode 100644 index 6068fc48..00000000 --- a/sop-sdk/sdk-nodejs/common/Class.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * 面相对象辅助类,可实现类的创建,继承,方法重写 - * -
- //-------------------------
- // JS类的创建,继承
- //-------------------------
-
- // 例子1:-------------------------
- // 创建一个父类
- var Person = Class.create({
-        // 构造函数
-        init:function(option){
-            this.name = option.name;
-        }
-        ,getName:function() {
-            return this.name;
-        }
-    });
-
- // 声明类实例
- var Jim = new Person({name:'Jim'});
- console.log('Jim name:' + Jim.getName())
-
- //例子2:-------------------------
-
- // 创建一个类,继承Person类,并重写getName
- var Man = Class.create({
-        init:function(option) {
-            this._super(option);// 调用父类构造函数
-            this.age = option.age;
-        }
-        // 重写父类方法
-        ,getName:function() {
-            // 调用父类的getName()
-            var name = this._super();
-            return '我重写了getName方法:{'+name+'}';
-        }
-    },Person);
-
- var man = new Man({name:'Tom',age:22});
- console.log('man name:' + man.getName())
-
- console.log('Jim instanceof Person: ' + (Jim instanceof Person));
- console.log('man instanceof Person: ' + (man instanceof Person));
- 
- * - */ -exports.Class = (function () { - // ------Class Creation------ - var initializing = false, - fnTest = /xyz/.test(function () { - xyz; - }) ? /\b_super\b/ : /.*/; - - // The base Class implementation (does nothing) - this.Class = function () { - }; - - // Create a new Class that inherits from this class - Class.extend = function (prop) { - var _super = this.prototype; - - // Instantiate a base class (but only create the instance, - // don't run the init constructor) - initializing = true; - var prototype = new this(); - initializing = false; - - // Copy the properties over onto the new prototype - for (var name in prop) { - // Check if we're overwriting an existing function - prototype[name] = typeof prop[name] == 'function' && typeof _super[name] == 'function' && fnTest.test(prop[name]) ? (function (name, fn) { - return function () { - var tmp = this._super; - - // Add a new ._super() method that is the same method - // but on the super-class - this._super = _super[name]; - - // The method only need to be bound temporarily, so we - // remove it when we're done executing - var ret = fn.apply(this, arguments); - this._super = tmp; - - return ret; - }; - })(name, prop[name]) : prop[name]; - } - - // The dummy class constructor - function Class() { - // All construction is actually done in the init method - if (!initializing && this.init) this.init.apply(this, arguments); - } - - // Populate our constructed prototype object - Class.prototype = prototype; - - // Enforce the constructor to be what we expect - Class.prototype.constructor = Class; - - // And make this class extendable - Class.extend = arguments.callee; - - return Class; - };// ------Class Creation end------ - - - return { - /** - * 创建一个类 - * @param option 类方法,json数据 - * @param parentClass 父类 - */ - create: function (option, parentClass) { - if (!parentClass) { - parentClass = Class; - } - return parentClass.extend(option); - } - }; - -})(); diff --git a/sop-sdk/sdk-nodejs/common/OpenClient.js b/sop-sdk/sdk-nodejs/common/OpenClient.js index 2397021c..fe0d1820 100644 --- a/sop-sdk/sdk-nodejs/common/OpenClient.js +++ b/sop-sdk/sdk-nodejs/common/OpenClient.js @@ -1,184 +1,213 @@ -const needle = require('needle'); +const axios = require('axios'); const moment = require('moment'); +const qs = require('qs'); -const {Class} = require('./Class'); -const {RequestType} = require('./RequestType'); -const {SignUtil} = require('./SignUtil'); -const {BaseRequest} = require('../request/BaseRequest'); +const RequestType = require('./RequestType'); +const SignUtil = require('./SignUtil'); +const BaseRequest = require('./BaseRequest'); + +const IS_RUN_IN_BROWSER = typeof window !== 'undefined' && this === window; const HEADERS = {'Accept-Encoding': 'identity'}; -const getHeaders = function (headers) { - if (!headers) { - return HEADERS; +const getHeaders = (headers = {}) => { + return Object.assign({}, headers, HEADERS); +}; + +const parseResponse = (error, response, request) => { + if (!error && response.status === 200) { + return request.parseResponse(response.data); + } else { + return { // 重新封装请求异常回调,以防中断 + msg: '请求异常', + code: '502', + sub_msg: `${error}`, + sub_code: 'isv.invalid-server' + }; + } +}; + +const buildParams = (instance, request, token) => { + const {appId, privateKey} = instance; + const allParams = { + 'app_id': appId, + 'method': request.getMethod(), + 'charset': 'UTF-8', + 'sign_type': 'RSA2', + 'timestamp': moment().format('YYYY-MM-DD HH:mm:ss'), + 'version': request.getVersion(), + 'biz_content': JSON.stringify(request.bizModel) + }; + + if (token) { + allParams['app_auth_token'] = token; + } + // 创建签名 + allParams.sign = SignUtil.createSign(allParams, privateKey, 'RSA2'); + return allParams; +}; + +const executeRequest = async (instance = {}, request, token, callback, customOptions = {}) => { + const params = buildParams(instance, request, token); + const {url} = instance; + let {headers} = customOptions; + const config = { + url, + method: 'POST', + params: undefined, + data: undefined + }; + headers = getHeaders(headers); + const requestType = request.getRealRequestType(); + switch (requestType) { + case RequestType.GET: { + config.method = 'GET'; + config.params = params; + } + break; + case RequestType.POST_FORM: { + headers = Object.assign(headers, { + 'Content-Type': 'application/x-www-form-urlencoded' + }); + config.data = qs.stringify(params); + } + break; + case RequestType.POST_JSON: { + config.data = params; + } + break; + case RequestType.POST_FILE: { + let formData; + if (IS_RUN_IN_BROWSER) { + formData = new window.FormData() + (request.files || []).forEach(({name, path}) => { + formData.append(name, path, { + contentType: 'application/octet-stream' + }); + }); + } else { + const fs = require('fs'); + const fd = require('form-data'); + formData = new fd(); + (request.files || []).forEach(({name, path}) => { + formData.append(name, fs.createReadStream(path), { + contentType: 'application/octet-stream' + }); + }); + headers = Object.assign(headers, formData.getHeaders()); + } + Object.keys(params).forEach(key => { + const value = params[key]; + if (!(typeof key === 'undefined' || typeof value === 'undefined')) { + formData.append(key, params[key]); + } + }); + config.data = formData; + } + break; + default: { + callback(parseResponse(new Error('request.getRequestType()类型不正确'), undefined, request)); + return; + } } - for (const key in HEADERS) { - headers[key] = HEADERS[key]; + try { + config['headers'] = headers; + const response = await axios.request(config); + callback(parseResponse(undefined, response, request)); + } catch (error) { + callback(parseResponse(error, undefined, request)); } - return headers; }; -const OpenClient = Class.create({ +module.exports = class OpenClient { /** * 初始化客户端 * @param appId 应用ID * @param privateKey 应用私钥,2048位,PKCS8 * @param url 请求url */ - init: function (appId, privateKey, url) { - this.appId = appId; - this.privateKey = privateKey; - this.url = url; - }, + constructor(appId, privateKey, url) { + this.appId = appId || ''; + this.privateKey = privateKey || ''; + this.url = url || ''; + } + + setAppId(appId) { + this.appId = appId || ''; + return this; + } + + setPrivateKey(privateKey) { + this.privateKey = privateKey || ''; + return this; + } + + setUrl(url) { + this.url = url || ''; + return this; + } + /** * 发送请求 * @param request 请求类 * @param callback 回调函数,参数json(undefined则使用executeSync) + * @param options 自定义参数,如headers */ - execute: function (request, callback) { + execute(request, callback, options) { if (typeof callback == 'function') { - this.executeToken(request, null, callback); + return this.executeToken(request, null, callback, options); } else { - return this.executeSync(request); + return this.executeSync(request, options); } - }, + } + /** * 发送同步请求 * @param request 请求类 + * @param options 自定义参数,如headers * */ - executeSync: function (request) { + executeSync(request, options) { return new Promise((resolve) => { - this.execute(request, res => { + const _ = this.execute(request, res => { resolve(res); - }); + }, options); }); - }, + } + /** * 发送请求 * @param request 请求类 * @param token token * @param callback 回调函数,参数json(undefined则使用executeTokenSync) + * @param options 自定义参数,如headers */ - executeToken: function (request, token, callback) { + async executeToken(request, token, callback, options) { if (!(request instanceof BaseRequest)) { throw 'request类未继承BaseRequest'; } if (typeof callback == 'function') { - const requestType = request.getRequestType(); - if (request.files) { - this._postFile(request, callback); - } else { - switch (requestType) { - case RequestType.GET: - this._get(request, callback); - break; - case RequestType.POST_FORM: - this._postForm(request, callback); - break; - case RequestType.POST_JSON: - this._postJson(request, callback); - break; - case RequestType.POST_FILE: - this._postFile(request, callback); - break; - default: { - throw 'request.getRequestType()类型不正确'; - } - } + const files = request.files; + if (files && files.length > 0) { + request.setForceRequestType(RequestType.POST_FILE); } + return await executeRequest(this, request, token, callback, options); } else { return this.executeTokenSync(request, token); } - }, + } + /** * 发送同步请求 * @param request 请求类 * @param token token + * @param options 自定义参数,如headers */ - executeTokenSync: function (request, token) { + executeTokenSync(request, token, options) { return new Promise((resolve) => { - this.executeToken(request, token, res => { + const _ = this.executeToken(request, token, res => { resolve(res); - }); - }); - }, - _get: function (request, callback) { - const allParams = this._buildParams(request); - 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)); - }); - }, - _postForm: function (request, callback) { - const allParams = this._buildParams(request); - const that = this; - needle.request('POST', this.url, allParams, { - headers: getHeaders({ - 'Content-Type': 'application/x-www-form-urlencoded' - }) - }, function (error, response) { - callback(that._parseResponse(error, response, request)); - }); - }, - _postJson: function (request, callback) { - const allParams = this._buildParams(request); - const that = this; - needle.request('POST', this.url, allParams, { - headers: getHeaders(), json: true - }, function (error, response) { - callback(that._parseResponse(error, response, request)); - }); - }, - _postFile: function (request, callback) { - const allParams = this._buildParams(request); - 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)); + }, options); }); - }, - _parseResponse: function (error, response, request) { - if (!error && response.statusCode === 200) { - return request.parseResponse(response.body); - } else { - // throw '请求异常:' + error - return { // 重新封装请求异常回调,以防中断 - msg: '请求异常', - code: '502', - sub_msg: `${error}`, - sub_code: 'isv.invalid-server' - }; - } - }, - _buildParams: function (request, token) { - const allParams = { - 'app_id': this.appId, - 'method': request.getMethod(), - 'charset': 'UTF-8', - 'sign_type': 'RSA2', - 'timestamp': moment().format('YYYY-MM-DD HH:mm:ss'), - 'version': request.getVersion(), - 'biz_content': JSON.stringify(request.bizModel) - }; - - if (token) { - allParams['app_auth_token'] = token; - } - // 创建签名 - const sign = SignUtil.createSign(allParams, this.privateKey, 'RSA2'); - allParams.sign = sign; - return allParams; } -}); -module.exports = OpenClient; +}; diff --git a/sop-sdk/sdk-nodejs/common/RequestType.js b/sop-sdk/sdk-nodejs/common/RequestType.js index 717d99f5..f745548d 100644 --- a/sop-sdk/sdk-nodejs/common/RequestType.js +++ b/sop-sdk/sdk-nodejs/common/RequestType.js @@ -1,4 +1,4 @@ -exports.RequestType = { +module.exports = { GET: 'GET', POST_FORM: 'POST_FORM', POST_JSON: 'POST_JSON', diff --git a/sop-sdk/sdk-nodejs/common/SignUtil.js b/sop-sdk/sdk-nodejs/common/SignUtil.js index 4c141676..98e2ceb6 100644 --- a/sop-sdk/sdk-nodejs/common/SignUtil.js +++ b/sop-sdk/sdk-nodejs/common/SignUtil.js @@ -11,7 +11,7 @@ const PEM_END = '\n-----END PRIVATE KEY-----'; /** * rsa签名参考:https://www.jianshu.com/p/145eab95322c */ -exports.SignUtil = { +module.exports = { /** * 创建签名 * @param params 请求参数 @@ -68,22 +68,21 @@ exports.SignUtil = { */ getSignContent: function (params) { const paramNames = []; - // 获取对象中的Key - paramNames.push(...Object.keys(params || {}) - // 过滤无效的KeyValue - .filter(paramName => { - // 参数名不为undefined且参数值不为undefined - return !(typeof paramName === undefined || typeof params[paramName] === undefined); - })); + for (const key in params) { + paramNames.push(key); + } paramNames.sort(); - // 合成签名字符串 - const paramNameValue = paramNames.map(paramName => { - const val = params[paramName]; - return `${paramName}=${val}`; - }); + const paramNameValue = []; + for (let i = 0, len = paramNames.length; i < len; i++) { + const paramName = paramNames[i]; + const val = params[paramName]; + if (paramName && val) { + paramNameValue.push(`${paramName}=${val}`); + } + } return paramNameValue.join('&'); } }; diff --git a/sop-sdk/sdk-nodejs/main.js b/sop-sdk/sdk-nodejs/main.js index d4dcd3e5..766285c4 100644 --- a/sop-sdk/sdk-nodejs/main.js +++ b/sop-sdk/sdk-nodejs/main.js @@ -1,6 +1,6 @@ const OpenClient = require('./common/OpenClient'); -const {StoryGetRequest} = require('./request/StoryGetRequest'); +const StoryGetRequest = require('./request/StoryGetRequest'); // 应用ID const appId = '2019032617262200001'; @@ -10,61 +10,35 @@ const privateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqW const url = 'http://localhost:8081'; // 创建客户端 -const openClient = new OpenClient(appId, privateKey, url); +const openClient = new OpenClient().setUrl(url).setAppId(appId).setPrivateKey(privateKey); -function test() { +(async () => { // 创建请求 const request = new StoryGetRequest(); // 设置业务参数 - request.bizModel = { + const bizModel = { id: 111, name: 'jim' }; + request.setBizModel(bizModel); // 添加上传文件 - // request.files = [ + // 批量添加 + // const files = [ // // name: 表单名称,path:文件全路径 - // {name: 'file1', path: `${__dirname}/aa.txt`}, - // {name: 'file2', path: `${__dirname}/bb.txt`} - // ] - - openClient.execute(request, data => { - console.log('异步请求'); - // 成功 - if (!data.sub_code) { - console.log('成功', data); - } else { - console.error('失败', data); - } - }); - - // 使用Promise进行封装 - openClient.executeSync(request).then(data => { - console.log('同步请求-Promise'); - // 成功 - if (!data.sub_code) { - console.log('成功', data); - } else { - console.error('失败', data); - } - }); - - // 使用Async/Await进行封装 - async function syncRequest() { - const data = await openClient.execute(request); - console.log('同步请求-Async/Await'); - // 成功 - if (!data.sub_code) { - console.log('成功', data); - } else { - console.error('失败', data); - } + // {name: 'file1', path: `${__dirname}/main.js`}, + // {name: 'file2', path: `${__dirname}/readme.md`} + // ]; + // request.setFiles(files); + // // 单个添加 + // request.addFile('file3', `${__dirname}/package.json`); + + const data = await openClient.executeSync(request); + // 成功 + if (!data.sub_code) { + console.log('成功', data); + } else { + console.error('失败', data); } - - syncRequest(); -} - - -test(); - +})(); diff --git a/sop-sdk/sdk-nodejs/package.json b/sop-sdk/sdk-nodejs/package.json index d1611bd4..db3bac8e 100644 --- a/sop-sdk/sdk-nodejs/package.json +++ b/sop-sdk/sdk-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "sdk-nodejs", - "version": "1.0.0", + "version": "1.1.0", "description": "", "main": "index.js", "scripts": { @@ -10,8 +10,11 @@ "author": "", "license": "ISC", "dependencies": { + "axios": "^0.21.1", + "form-data": "^4.0.0", + "isarray": "^2.0.5", "jsrsasign": "^8.0.19", "moment": "^2.27.0", - "needle": "^2.5.0" + "qs": "^6.10.1" } } diff --git a/sop-sdk/sdk-nodejs/request/BaseRequest.js b/sop-sdk/sdk-nodejs/request/BaseRequest.js deleted file mode 100644 index 53c36f2f..00000000 --- a/sop-sdk/sdk-nodejs/request/BaseRequest.js +++ /dev/null @@ -1,48 +0,0 @@ -const {Class} = require('../common/Class'); - -/** - * 请求类父类 - */ -exports.BaseRequest = Class.create({ - init: function () { - this.bizModel = {}; - /* - [ - {name: 'file1', path: 'd:/dd/1.txt'}, - {name: 'file2', path: 'd:/dd/2.txt'} - ] - */ - this.files = []; - }, - /** - * 返回接口名称 - */ - getMethod: function () { - throw `未实现BaseRequest类getMethod()方法`; - }, - /** - * 返回版本号 - */ - getVersion: function () { - throw '未实现BaseRequest类getVersion()方法'; - }, - /** - * 返回请求类型,使用RequestType.js - */ - getRequestType: function () { - throw '未实现BaseRequest类getRequestType()方法'; - }, - /** - * 解析返回结果,子类可以覆盖实现 - * @param responseData 服务器返回内容 - * @returns 返回结果 - */ - parseResponse: function (responseData) { - let data = responseData['error_response']; - if (!data) { - const dataNodeName = this.getMethod().replace(/\./g, '_') + '_response'; - data = responseData[dataNodeName]; - } - return data; - } -}); diff --git a/sop-sdk/sdk-nodejs/request/StoryGetRequest.js b/sop-sdk/sdk-nodejs/request/StoryGetRequest.js index ea5f51bb..243084a7 100644 --- a/sop-sdk/sdk-nodejs/request/StoryGetRequest.js +++ b/sop-sdk/sdk-nodejs/request/StoryGetRequest.js @@ -1,22 +1,19 @@ -const {Class} = require('../common/Class'); -const {RequestType} = require('../common/RequestType'); -const {BaseRequest} = require('./BaseRequest'); +const BaseRequest = require('../common/BaseRequest'); +const RequestType = require('../common/RequestType'); /** * 创建一个请求类,继承BaseRequest,重写三个函数 */ -const StoryGetRequest = Class.create({ - - getMethod: function () { +module.exports = class StoryGetRequest extends BaseRequest { + getMethod() { return 'story.get'; - }, - getVersion: function () { - return '1.0'; - }, - getRequestType: function () { - return RequestType.GET; } -}, BaseRequest); // 继承BaseRequest + getVersion() { + return '1.0'; + } -module.exports.StoryGetRequest = StoryGetRequest; + getRequestType() { + return RequestType.GET; + } +}; diff --git a/sop-sdk/sdk-nodejs/testClass.js b/sop-sdk/sdk-nodejs/testClass.js deleted file mode 100644 index 866fe62a..00000000 --- a/sop-sdk/sdk-nodejs/testClass.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 演示JS面相对象,包括类的创建,继承,方法重写 - * 运行:node testClass.js - */ - -const {Class} = require('./common/Class'); - -function testClass() { - //------------------------- - // JS类的创建,继承 - //------------------------- - - // 例子1:------------------------- - // 创建一个父类 - var Person = Class.create({ - // 构造函数 - init: function (option) { - this.name = option.name; - } - , getName: function () { - return this.name; - } - }); - - // 声明类实例 - var Jim = new Person({name: 'Jim'}); - console.log('Jim name:' + Jim.getName()); - - //例子2:------------------------- - - // 创建一个类,继承Person类,并重写getName - var Man = Class.create({ - init: function (option) { - this._super(option);// 调用父类构造函数 - this.age = option.age; - } - // 重写父类方法 - , getName: function () { - // 调用父类的getName() - var name = this._super(); - return '我重写了getName方法:{' + name + '}'; - } - }, Person); - - var man = new Man({name: 'Tom', age: 22}); - console.log('man name:' + man.getName()); - - console.log('Jim instanceof Person: ' + (Jim instanceof Person)); - console.log('man instanceof Person: ' + (man instanceof Person)); -} - -testClass(); From 3ceb8cdc93475f1b3ee8a81039ab8431b1222d8a Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 14:13:20 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs-axios/.gitignore | 16 -- sop-sdk/sdk-nodejs-axios/common/OpenClient.js | 213 ------------------ .../sdk-nodejs-axios/common/RequestType.js | 6 - sop-sdk/sdk-nodejs-axios/common/SignUtil.js | 88 -------- sop-sdk/sdk-nodejs-axios/main.js | 44 ---- sop-sdk/sdk-nodejs-axios/package.json | 21 -- sop-sdk/sdk-nodejs-axios/readme.md | 10 - .../request/StoryGetRequest.js | 19 -- .../common/BaseRequest.js | 0 9 files changed, 417 deletions(-) delete mode 100644 sop-sdk/sdk-nodejs-axios/.gitignore delete mode 100644 sop-sdk/sdk-nodejs-axios/common/OpenClient.js delete mode 100644 sop-sdk/sdk-nodejs-axios/common/RequestType.js delete mode 100644 sop-sdk/sdk-nodejs-axios/common/SignUtil.js delete mode 100644 sop-sdk/sdk-nodejs-axios/main.js delete mode 100644 sop-sdk/sdk-nodejs-axios/package.json delete mode 100644 sop-sdk/sdk-nodejs-axios/readme.md delete mode 100644 sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js rename sop-sdk/{sdk-nodejs-axios => sdk-nodejs}/common/BaseRequest.js (100%) diff --git a/sop-sdk/sdk-nodejs-axios/.gitignore b/sop-sdk/sdk-nodejs-axios/.gitignore deleted file mode 100644 index 9ad28d23..00000000 --- a/sop-sdk/sdk-nodejs-axios/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -.DS_Store -node_modules/ -dist/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* -package-lock.json -tests/**/coverage/ - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln diff --git a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js b/sop-sdk/sdk-nodejs-axios/common/OpenClient.js deleted file mode 100644 index fe0d1820..00000000 --- a/sop-sdk/sdk-nodejs-axios/common/OpenClient.js +++ /dev/null @@ -1,213 +0,0 @@ -const axios = require('axios'); -const moment = require('moment'); -const qs = require('qs'); - -const RequestType = require('./RequestType'); -const SignUtil = require('./SignUtil'); -const BaseRequest = require('./BaseRequest'); - -const IS_RUN_IN_BROWSER = typeof window !== 'undefined' && this === window; - -const HEADERS = {'Accept-Encoding': 'identity'}; - -const getHeaders = (headers = {}) => { - return Object.assign({}, headers, HEADERS); -}; - -const parseResponse = (error, response, request) => { - if (!error && response.status === 200) { - return request.parseResponse(response.data); - } else { - return { // 重新封装请求异常回调,以防中断 - msg: '请求异常', - code: '502', - sub_msg: `${error}`, - sub_code: 'isv.invalid-server' - }; - } -}; - -const buildParams = (instance, request, token) => { - const {appId, privateKey} = instance; - const allParams = { - 'app_id': appId, - 'method': request.getMethod(), - 'charset': 'UTF-8', - 'sign_type': 'RSA2', - 'timestamp': moment().format('YYYY-MM-DD HH:mm:ss'), - 'version': request.getVersion(), - 'biz_content': JSON.stringify(request.bizModel) - }; - - if (token) { - allParams['app_auth_token'] = token; - } - // 创建签名 - allParams.sign = SignUtil.createSign(allParams, privateKey, 'RSA2'); - return allParams; -}; - -const executeRequest = async (instance = {}, request, token, callback, customOptions = {}) => { - const params = buildParams(instance, request, token); - const {url} = instance; - let {headers} = customOptions; - const config = { - url, - method: 'POST', - params: undefined, - data: undefined - }; - headers = getHeaders(headers); - const requestType = request.getRealRequestType(); - switch (requestType) { - case RequestType.GET: { - config.method = 'GET'; - config.params = params; - } - break; - case RequestType.POST_FORM: { - headers = Object.assign(headers, { - 'Content-Type': 'application/x-www-form-urlencoded' - }); - config.data = qs.stringify(params); - } - break; - case RequestType.POST_JSON: { - config.data = params; - } - break; - case RequestType.POST_FILE: { - let formData; - if (IS_RUN_IN_BROWSER) { - formData = new window.FormData() - (request.files || []).forEach(({name, path}) => { - formData.append(name, path, { - contentType: 'application/octet-stream' - }); - }); - } else { - const fs = require('fs'); - const fd = require('form-data'); - formData = new fd(); - (request.files || []).forEach(({name, path}) => { - formData.append(name, fs.createReadStream(path), { - contentType: 'application/octet-stream' - }); - }); - headers = Object.assign(headers, formData.getHeaders()); - } - Object.keys(params).forEach(key => { - const value = params[key]; - if (!(typeof key === 'undefined' || typeof value === 'undefined')) { - formData.append(key, params[key]); - } - }); - config.data = formData; - } - break; - default: { - callback(parseResponse(new Error('request.getRequestType()类型不正确'), undefined, request)); - return; - } - } - try { - config['headers'] = headers; - const response = await axios.request(config); - callback(parseResponse(undefined, response, request)); - } catch (error) { - callback(parseResponse(error, undefined, request)); - } -}; - -module.exports = class OpenClient { - /** - * 初始化客户端 - * @param appId 应用ID - * @param privateKey 应用私钥,2048位,PKCS8 - * @param url 请求url - */ - constructor(appId, privateKey, url) { - this.appId = appId || ''; - this.privateKey = privateKey || ''; - this.url = url || ''; - } - - setAppId(appId) { - this.appId = appId || ''; - return this; - } - - setPrivateKey(privateKey) { - this.privateKey = privateKey || ''; - return this; - } - - setUrl(url) { - this.url = url || ''; - return this; - } - - /** - * 发送请求 - * @param request 请求类 - * @param callback 回调函数,参数json(undefined则使用executeSync) - * @param options 自定义参数,如headers - */ - execute(request, callback, options) { - if (typeof callback == 'function') { - return this.executeToken(request, null, callback, options); - } else { - return this.executeSync(request, options); - } - } - - /** - * 发送同步请求 - * @param request 请求类 - * @param options 自定义参数,如headers - * */ - executeSync(request, options) { - return new Promise((resolve) => { - const _ = this.execute(request, res => { - resolve(res); - }, options); - }); - } - - /** - * 发送请求 - * @param request 请求类 - * @param token token - * @param callback 回调函数,参数json(undefined则使用executeTokenSync) - * @param options 自定义参数,如headers - */ - async executeToken(request, token, callback, options) { - if (!(request instanceof BaseRequest)) { - throw 'request类未继承BaseRequest'; - } - if (typeof callback == 'function') { - const files = request.files; - if (files && files.length > 0) { - request.setForceRequestType(RequestType.POST_FILE); - } - return await executeRequest(this, request, token, callback, options); - } else { - return this.executeTokenSync(request, token); - } - } - - /** - * 发送同步请求 - * @param request 请求类 - * @param token token - * @param options 自定义参数,如headers - */ - executeTokenSync(request, token, options) { - return new Promise((resolve) => { - const _ = this.executeToken(request, token, res => { - resolve(res); - }, options); - }); - } - -}; diff --git a/sop-sdk/sdk-nodejs-axios/common/RequestType.js b/sop-sdk/sdk-nodejs-axios/common/RequestType.js deleted file mode 100644 index f745548d..00000000 --- a/sop-sdk/sdk-nodejs-axios/common/RequestType.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - GET: 'GET', - POST_FORM: 'POST_FORM', - POST_JSON: 'POST_JSON', - POST_FILE: 'POST_FILE' -}; diff --git a/sop-sdk/sdk-nodejs-axios/common/SignUtil.js b/sop-sdk/sdk-nodejs-axios/common/SignUtil.js deleted file mode 100644 index 98e2ceb6..00000000 --- a/sop-sdk/sdk-nodejs-axios/common/SignUtil.js +++ /dev/null @@ -1,88 +0,0 @@ -const {KJUR, hextob64} = require('jsrsasign'); - -const HashMap = { - SHA256withRSA: 'SHA256withRSA', - SHA1withRSA: 'SHA1withRSA' -}; - -const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n'; -const PEM_END = '\n-----END PRIVATE KEY-----'; - -/** - * rsa签名参考:https://www.jianshu.com/p/145eab95322c - */ -module.exports = { - /** - * 创建签名 - * @param params 请求参数 - * @param privateKey 私钥,PKCS8 - * @param signType 签名类型,RSA,RSA2 - * @returns 返回签名内容 - */ - createSign(params, privateKey, signType) { - const content = this.getSignContent(params); - return this.sign(content, privateKey, signType); - }, - sign: function (content, privateKey, signType) { - if (signType.toUpperCase() === 'RSA') { - return this.rsaSign(content, privateKey, HashMap.SHA1withRSA); - } else if (signType.toUpperCase() === 'RSA2') { - return this.rsaSign(content, privateKey, HashMap.SHA256withRSA); - } else { - throw 'signType错误'; - } - }, - /** - * rsa签名 - * @param content 签名内容 - * @param privateKey 私钥 - * @param hash hash算法,SHA256withRSA,SHA1withRSA - * @returns 返回签名字符串,base64 - */ - rsaSign: function (content, privateKey, hash) { - privateKey = this._formatKey(privateKey); - // 创建 Signature 对象 - const signature = new KJUR.crypto.Signature({ - alg: hash, - //!这里指定 私钥 pem! - prvkeypem: privateKey - }); - signature.updateString(content); - const signData = signature.sign(); - // 将内容转成base64 - return hextob64(signData); - }, - _formatKey: function (key) { - if (!key.startsWith(PEM_BEGIN)) { - key = PEM_BEGIN + key; - } - if (!key.endsWith(PEM_END)) { - key = key + PEM_END; - } - return key; - }, - /** - * 获取签名内容 - * @param params 请求参数 - * @returns {string} - */ - getSignContent: function (params) { - const paramNames = []; - for (const key in params) { - paramNames.push(key); - } - - paramNames.sort(); - - const paramNameValue = []; - - for (let i = 0, len = paramNames.length; i < len; i++) { - const paramName = paramNames[i]; - const val = params[paramName]; - if (paramName && val) { - paramNameValue.push(`${paramName}=${val}`); - } - } - return paramNameValue.join('&'); - } -}; diff --git a/sop-sdk/sdk-nodejs-axios/main.js b/sop-sdk/sdk-nodejs-axios/main.js deleted file mode 100644 index 766285c4..00000000 --- a/sop-sdk/sdk-nodejs-axios/main.js +++ /dev/null @@ -1,44 +0,0 @@ -const OpenClient = require('./common/OpenClient'); - -const StoryGetRequest = require('./request/StoryGetRequest'); - -// 应用ID -const appId = '2019032617262200001'; -// 应用私钥,2048位,PKCS8 -const privateKey = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ='; -// 接口url -const url = 'http://localhost:8081'; - -// 创建客户端 -const openClient = new OpenClient().setUrl(url).setAppId(appId).setPrivateKey(privateKey); - -(async () => { - // 创建请求 - const request = new StoryGetRequest(); - - // 设置业务参数 - const bizModel = { - id: 111, - name: 'jim' - }; - request.setBizModel(bizModel); - - // 添加上传文件 - // 批量添加 - // const files = [ - // // name: 表单名称,path:文件全路径 - // {name: 'file1', path: `${__dirname}/main.js`}, - // {name: 'file2', path: `${__dirname}/readme.md`} - // ]; - // request.setFiles(files); - // // 单个添加 - // request.addFile('file3', `${__dirname}/package.json`); - - const data = await openClient.executeSync(request); - // 成功 - if (!data.sub_code) { - console.log('成功', data); - } else { - console.error('失败', data); - } -})(); diff --git a/sop-sdk/sdk-nodejs-axios/package.json b/sop-sdk/sdk-nodejs-axios/package.json deleted file mode 100644 index 88232a74..00000000 --- a/sop-sdk/sdk-nodejs-axios/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "sdk-nodejs", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^0.21.1", - "form-data": "^4.0.0", - "isarray": "^2.0.5", - "isobject": "^4.0.0", - "jsrsasign": "^8.0.19", - "moment": "^2.27.0", - "qs": "^6.10.1" - } -} diff --git a/sop-sdk/sdk-nodejs-axios/readme.md b/sop-sdk/sdk-nodejs-axios/readme.md deleted file mode 100644 index 79b852e5..00000000 --- a/sop-sdk/sdk-nodejs-axios/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -- 执行`npm install --registry=https://registry.npm.taobao.org` - -- 执行`node main.js`进行测试 - -## 封装步骤 - -1. 新建request类,继承BaseRequest,参考`StoryGetRequest.js` - -2. 调用接口,参考`main.js` - diff --git a/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js b/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js deleted file mode 100644 index 243084a7..00000000 --- a/sop-sdk/sdk-nodejs-axios/request/StoryGetRequest.js +++ /dev/null @@ -1,19 +0,0 @@ -const BaseRequest = require('../common/BaseRequest'); -const RequestType = require('../common/RequestType'); - -/** - * 创建一个请求类,继承BaseRequest,重写三个函数 - */ -module.exports = class StoryGetRequest extends BaseRequest { - getMethod() { - return 'story.get'; - } - - getVersion() { - return '1.0'; - } - - getRequestType() { - return RequestType.GET; - } -}; diff --git a/sop-sdk/sdk-nodejs-axios/common/BaseRequest.js b/sop-sdk/sdk-nodejs/common/BaseRequest.js similarity index 100% rename from sop-sdk/sdk-nodejs-axios/common/BaseRequest.js rename to sop-sdk/sdk-nodejs/common/BaseRequest.js From 4eae92b03327eb91975c52b88798c115455b240e Mon Sep 17 00:00:00 2001 From: Changeden Date: Wed, 14 Apr 2021 14:41:35 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-sdk/sdk-nodejs/common/OpenClient.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sop-sdk/sdk-nodejs/common/OpenClient.js b/sop-sdk/sdk-nodejs/common/OpenClient.js index fe0d1820..5c79178a 100644 --- a/sop-sdk/sdk-nodejs/common/OpenClient.js +++ b/sop-sdk/sdk-nodejs/common/OpenClient.js @@ -79,7 +79,7 @@ const executeRequest = async (instance = {}, request, token, callback, customOpt case RequestType.POST_FILE: { let formData; if (IS_RUN_IN_BROWSER) { - formData = new window.FormData() + formData = new window.FormData(); (request.files || []).forEach(({name, path}) => { formData.append(name, path, { contentType: 'application/octet-stream' @@ -167,8 +167,8 @@ module.exports = class OpenClient { * @param options 自定义参数,如headers * */ executeSync(request, options) { - return new Promise((resolve) => { - const _ = this.execute(request, res => { + return new Promise(async (resolve) => { + await this.execute(request, res => { resolve(res); }, options); }); @@ -203,8 +203,8 @@ module.exports = class OpenClient { * @param options 自定义参数,如headers */ executeTokenSync(request, token, options) { - return new Promise((resolve) => { - const _ = this.executeToken(request, token, res => { + return new Promise(async (resolve) => { + await this.executeToken(request, token, res => { resolve(res); }, options); });