UNPKG

apis-scf

Version:

Apis Serverless Compute Function NodeJS Package

1,312 lines (1,182 loc) 44 kB
// const os = require( 'os' ); // const stream = require( 'stream' ); // const Apis = require( 'apis-core' ); // const ArtTemplate = require( 'art-template' ); // const Minify = require( 'html-minifier' ); // const Cookie = require( 'cookie' ); // const Redis = require( 'ioredis' ); // const Busboy = require( 'busboy' ); const HelperError = { /** * 异常 * @param message * @param name * @param code */ exception : function ( message, name = 'ApisException', code = 0 ) { this.message = message; this.name = name; this.code = code; this.stack = (new Error()).stack; } }; const HelperMiddleware = { /** * 验证登录 */ verifyLogin : async function ( requestData, skipScene = [] ) { //方式 let _session_method = CONFIG[ 'Base' ].session.method; //cookie名称 let _cookie_name = CONFIG[ 'Base' ].session.name; //登录数据 let _login_data = null; //跳过场景 if ( skipScene.length >= 1 && skipScene.indexOf( requestData.path.method ) !== -1 ) { return requestData; } //判断cookie name if ( !requestData.cookie.hasOwnProperty( _cookie_name ) ) { throw new HelperError.exception( '' + _cookie_name + ' 不能为空', 'login' ); } //根据不同方式获取数据 if ( 'cookie' === _session_method ) { _login_data = JSON.parse( requestData.cookie[ _cookie_name ] ); } else if ( 'cache' === _session_method ) { _login_data = await HelperCache.get( requestData.cookie[ _cookie_name ] ); if ( Apis.Util.Base.isEmpty( _login_data ) ) { throw new HelperError.exception( '获取登录数据失败', 'login' ); } } else { throw new HelperError.exception( '登录数据存储方式异常', 'login' ); } //状态 if ( Apis.Util.Base.checkFailure( _login_data.login.status ) ) { throw new HelperError.exception( '登录状态失效', 'login' ); } //过期时间 if ( Number( _login_data.login.expiration_time ) < Apis.Util.Time.getTimestamp() ) { throw new HelperError.exception( '登录过期失效', 'login' ); } //登录数据赋值 requestData.session = _login_data; return requestData; }, /** * 验证签名 * @param requestData * @param skipScene * @returns {{result: null, message: string, status: boolean}} */ verifySignature : async function ( requestData, skipScene = [] ) { //**********************************************************/ // 没有开启,跳过 //**********************************************************/ if ( CONFIG[ 'Base' ].request.verify.enable !== true ) { return requestData; } //**********************************************************/ // 不是来自网关,跳过 //**********************************************************/ if ( !HelperBase.checkRequestIsApiGateway( requestData.header ) ) { return requestData; } //**********************************************************/ // 跳过场景 //**********************************************************/ if ( skipScene.length >= 1 && skipScene.indexOf( requestData.path.method ) !== -1 ) { return requestData; } //Apis.Util.Base.log( requestData, '验证签名请求数据' ); //**********************************************************/ // 判断必须数据是否存在 //**********************************************************/ // let _request_signature = null; if ( requestData.header.hasOwnProperty( 'x-apis-request-signature' ) ) { _request_signature = requestData.header[ 'x-apis-request-signature' ]; } else if ( requestData.all.hasOwnProperty( 'x-apis-request-signature' ) ) { _request_signature = requestData.all[ 'x-apis-request-signature' ]; //删除all中的x-apis-request-signature,不参与签名计算 delete requestData.all[ 'x-apis-request-signature' ]; } else { throw new Error( 'x-apis-request-signature不能为空' ); } // let _request_time = null; if ( requestData.header.hasOwnProperty( 'x-apis-request-time' ) ) { _request_time = requestData.header[ 'x-apis-request-time' ]; } else if ( requestData.all.hasOwnProperty( 'x-apis-request-time' ) ) { _request_time = requestData.all[ 'x-apis-request-time' ]; //删除all中的x-apis-request-time,不参与签名计算 delete requestData.all[ 'x-apis-request-time' ]; } else { throw new Error( 'x-apis-request-time不能为空' ); } //判断请求时间是否过期 let _now_time = Number( Apis.Util.Time.getTimestamp() ); let _expire_time = Number( Number( _request_time ) + Number( CONFIG[ 'Base' ].request.verify.config.expire ) ); if ( _expire_time < _now_time ) { throw new Error( '请求过期' ); } // let _request_rand = null; if ( requestData.header.hasOwnProperty( 'x-apis-request-rand' ) ) { _request_rand = requestData.header[ 'x-apis-request-rand' ]; } else if ( requestData.all.hasOwnProperty( 'x-apis-request-rand' ) ) { _request_rand = requestData.all[ 'x-apis-request-rand' ]; //删除all中的x-apis-request-rand,不参与签名计算 delete requestData.all[ 'x-apis-request-rand' ]; } else { throw new Error( 'x-apis-request-rand不能为空' ); } //**********************************************************/ // signature //**********************************************************/ let _signature_data = Object.assign( requestData.all, { _method : requestData.server.method, _protocol : requestData.server.protocol, _host : requestData.server.host, _path : requestData.server.path, _time : _request_time, _rand : _request_rand } ); let _verify_signature = Apis.Util.Security.signatureVerify( CONFIG[ 'Base' ].request.verify.config.method, _request_signature, _signature_data, CONFIG[ 'Base' ].request.verify.config.key ); if ( Apis.Util.Base.checkFailure( _verify_signature ) ) { throw new Error( '请求签名验证失败' ); } return requestData; }, /** * 请求数据解析json * @param requestData * @returns {*} */ requestDataJsonParse : async function ( requestData ) { //处理all数据 let _all_data = requestData.all; for ( let key in _all_data ) { if ( !_all_data.hasOwnProperty( key ) ) { continue; } //是否json,转换 if ( Apis.Util.Base.isJson( _all_data[ key ] ) ) { requestData.all[ key ] = JSON.parse( _all_data[ key ] ); } } //处理post数据 let _post_data = requestData.post; for ( let key in _post_data ) { if ( !_post_data.hasOwnProperty( key ) ) { continue; } //是否json,转换 if ( Apis.Util.Base.isJson( _post_data[ key ] ) ) { requestData.post[ key ] = JSON.parse( _post_data[ key ] ); } } return requestData; }, /** * 验证语言 * @param requestData */ verifyLanguage : async function ( requestData ) { // 允许的语言数组 let _language_list = [ 'zh-cn', 'en-us', 'zh-tw' ]; // 默认语言 let _language_default = 'zh-cn'; // 语言cookie名称 let _cookie_name = 'language'; // let _language_value = null; if ( requestData.all.hasOwnProperty( _cookie_name ) ) { // 使用参数指定语言 _language_value = requestData.all[ _cookie_name ]; } else { if ( requestData.cookie.hasOwnProperty( _cookie_name ) ) { // 使用cookie指定语言 _language_value = requestData.cookie[ _cookie_name ]; } else { // 侦测语言 _language_value = Apis.Util.Base.getAcceptLanguage( _language_list, requestData.client.language ); } } // 判断语言是否在合法语言列表中,不存在就用默认值 if ( _language_list.indexOf( _language_value ) === -1 ) { _language_value = _language_default; } // 设置cookie语言 HelperCookie.set( _cookie_name, _language_value ); // 加载远程语言 return requestData; } }; const HelperCookie = { data : [], set : function ( name, data, time ) { //是否加密 if ( CONFIG[ 'Base' ].cookie.encryption.enable === true ) { //开头加@#@识别是否加密 data = '@#@' + Apis.Util.Security.encrypt( 'aes-128-ecb', JSON.stringify( data ), CONFIG[ 'Base' ].cookie.encryption.key, {} ); } // let _options = JSON.parse( JSON.stringify( CONFIG[ 'Base' ].cookie.config ) ); _options.maxAge = time ? time : CONFIG[ 'Base' ].cookie.config.maxAge; // let _item = Cookie.serialize( name, data, _options ); // this.data.push( _item ); // return this; }, delete : function ( name ) { let _options = JSON.parse( JSON.stringify( CONFIG[ 'Base' ].cookie.config ) ); _options.maxAge = -1; // let _item = Cookie.serialize( name, null, _options ); // this.data.push( _item ); // return this; } }; const HelperBase = { /** * 生成请求数据 * @param event * @returns Object */ buildRequestData : async function ( event ) { //**********************************************************/ // 变量 //**********************************************************/ //初始化 let _result = { get : {}, post : {}, all : {}, header : {}, cookie : {}, files : [], path : { method : '',//aaa.bbb.ccc.ddd module : '',//aaa controller : '',//bbb model : '',//ccc action : '',//ddd }, server : { protocol : '', host : '', path : '', method : '', }, client : { ip : '', agent : '', language : '', } }; //**********************************************************/ // server和client //**********************************************************/ if ( event.headers ) { //protocol _result.server.protocol = event.headers[ 'x-api-scheme' ] ? event.headers[ 'x-api-scheme' ] : ''; //host,判断是否带端口 _result.server.host = (event.headers.host.indexOf( ':' ) >= 0) ? event.headers.host.split( ':' )[ 0 ] : event.headers.host; //path _result.server.path = event.path ? event.path : ''; //method _result.server.method = event.httpMethod ? event.httpMethod.toUpperCase() : ''; //ip _result.client.ip = (event.requestContext && event.requestContext.hasOwnProperty( 'sourceIp' )) ? event.requestContext.sourceIp : '127.0.0.1'; //user-agent _result.client.agent = event.headers[ 'user-agent' ] ? event.headers[ 'user-agent' ] : ''; //language _result.client.language = event.headers[ 'accept-language' ] ? event.headers[ 'accept-language' ].toLowerCase() : 'zh-cn'; } //**********************************************************/ // 处理触发(定时)(腾讯云SCF) //**********************************************************/ if ( event.Message ) { let _message_data = {}; let _object_data = JSON.parse( event.Message ); for ( let key in _object_data ) { if ( !_object_data.hasOwnProperty( key ) ) { continue; } // _message_data[ key ] = decodeURIComponent( _object_data[ key ] ); } //追加到(all) _result.all = Object.assign( _result.all, _message_data ); } //**********************************************************/ // headers //**********************************************************/ if ( event.headers ) { let _header_data = {}; let _object_data = event.headers; for ( let key in _object_data ) { if ( !_object_data.hasOwnProperty( key ) ) { continue; } // _header_data[ key ] = _object_data[ key ]; } //header _result.header = _header_data; } //**********************************************************/ // cookie //**********************************************************/ if ( event.headers.cookie ) { //解析 let _cookie_object = Cookie.parse( event.headers.cookie ); //是否加密 if ( CONFIG[ 'Base' ].cookie.encryption.enable === true ) { for ( let key in _cookie_object ) { if ( !_cookie_object.hasOwnProperty( key ) ) { continue; } // let _temp_data = _cookie_object[ key ]; //判断是否@#@开头 if ( _temp_data.substr( 0, 3 ) === '@#@' ) { try { //去掉@#@ _temp_data = _temp_data.substr( 3 ); //解密 _temp_data = Apis.Util.Security.decrypt( 'aes-128-ecb', _temp_data, CONFIG[ 'Base' ].cookie.encryption.key, {} ); } catch ( e ) { Apis.Util.Base.log( _temp_data, 'Cookie解密失败', 'error' ); } } //解析 _cookie_object[ key ] = JSON.parse( _temp_data ); } } // _result.cookie = _cookie_object; } //**********************************************************/ // GET //**********************************************************/ if ( event.queryString ) { let _get_data = {}; let _object_data = event.queryString; for ( let key in _object_data ) { if ( !_object_data.hasOwnProperty( key ) ) { continue; } // let _value = _object_data[ key ]; //排除首字符非字母的参数 let _first_rule = /^[a-zA-Z].*/; if ( !_first_rule.test( key ) ) { continue; } //排除包含大写字母的参数 let _uppercase_rule = /[A-Z]/; if ( _uppercase_rule.test( key ) ) { continue; } //排除值为空的参数 if ( Apis.Util.Base.isEmpty( _value, false ) ) { continue; } //转码 _value = decodeURIComponent( _value ); //过滤 _value = Apis.Util.String.filter( _value ); //最后赋值 _get_data[ key ] = _value; } //GET _result.get = _get_data; //追加到all _result.all = Object.assign( _result.all, _get_data ); } //**********************************************************/ // 上传 //**********************************************************/ if ( event.headers.hasOwnProperty( 'content-type' ) && event.headers[ 'content-type' ].indexOf( 'multipart/form-data' ) >= 0 ) { //处理 await this._buildUploadData( event ).then( function ( res, rej ) { _result.files = res; } ); //设为空,防止后续处理 event.body = null; } //**********************************************************/ // POST //**********************************************************/ if ( event.body ) { let _post_data = {}; //转数组 let _post_array = event.body.split( '&' ); for ( let i = 0; i < _post_array.length; i++ ) { //转数组[0]=key;[1]=value let _temp = _post_array[ i ].split( '=' ); //排除首字符非字母的参数 let _first_rule = /^[a-zA-Z].*/; if ( !_first_rule.test( _temp[ 0 ] ) ) { continue; } //排除包含大写字母的参数 let _uppercase_rule = /[A-Z]/; if ( _uppercase_rule.test( _temp[ 0 ] ) ) { continue; } //排除值为空的参数 if ( Apis.Util.Base.isEmpty( _temp[ 1 ], false ) ) { continue; } //+号转空格 _temp[ 1 ] = _temp[ 1 ].replace( /\+/g, '%20' ); //转码 _temp[ 1 ] = decodeURIComponent( _temp[ 1 ] ); //过滤 _temp[ 1 ] = Apis.Util.String.filter( _temp[ 1 ] ); //赋值 _post_data[ _temp[ 0 ] ] = _temp[ 1 ]; } //POST _result.post = _post_data; //追加到all _result.all = Object.assign( _result.all, _post_data ); } //**********************************************************/ // 处理path //**********************************************************/ // 初始化 _result.path.method = 'init.init.init.init'; // path传值,格式:aa/bb/cc if ( event.pathParameters ) { // aaa/bbb/ccc 转 aaa.bbb.ccc 格式 if ( !Apis.Util.ArrayObject.objectPropertyNotSetOrEmpty( event.pathParameters, 'method' ) ) { // 把/换成.格式aaa/bbb/ccc换成aaa.bbb.ccc _result.path.method = event.pathParameters.method.replace( /\//g, '.' ); } } // post、get传值,格式:aa.bb.cc.dd.ee if ( !Apis.Util.ArrayObject.objectPropertyNotSetOrEmpty( _result.all, 'method' ) ) { _result.path.method = _result.all.method; } //aa.bb.cc.dd转数组 let _path_array = _result.path.method.split( '.' ); //第1个.之前的是module _result.path.module = _path_array[ 0 ] ? _path_array[ 0 ] : ''; //第1个.和第2个.之间的是controller,转驼峰passport-user-abc转PassportUserAbc _result.path.controller = _path_array[ 1 ] ? Apis.Util.String.stringToCamel( _path_array[ 1 ] ) : ''; //第2个.和第3个.之间的是model,转驼峰passport-user-abc转PassportUserAbc _result.path.model = _path_array[ 2 ] ? Apis.Util.String.stringToCamel( _path_array[ 2 ] ) : ''; //第3个.之后的所有都算做action _result.path.action = _path_array[ 3 ] ? _path_array[ 3 ] : ''; //**********************************************************/ // 返回 //**********************************************************/ return _result; }, /** * 生成上传数据 * @param event * @returns {[]} * @private */ _buildUploadData : async function ( event ) { let _result = []; let busboy = new Busboy( { headers : event.headers } ); return new Promise( ( resolve, reject ) => { /** * busboy 需要 stream pipe 的方式来进行处理, * 我们将 body 解码为 buffer后, * 转换为 stream,最终 pipe 给 busbody */ let _body_buffer = Buffer.from( event.body, 'base64' ); let _buffer_stream = new stream.PassThrough(); _buffer_stream.end( _body_buffer ); _buffer_stream.pipe( busboy ); /** 接受到文件 */ busboy.on( 'file', ( fieldname, file, filename, encoding, mimetype ) => { let buf = Buffer.alloc( 0 ); //console.log( 'File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype ); //接受到文件的数据块,拼接出完整的 buffer file.on( 'data', function ( data ) { buf = Buffer.concat( [ buf, data ] ); } ); //文件的数据块接受完毕,生成字符串 file.on( 'end', function () { if ( filename.length !== 0 ) { //临时路径 let _file_path = os.tmpdir() + '/' + filename; // let _file_data_base64 = buf.toString( 'base64' ); // let _file_data_buffer = Buffer.from( _file_data_base64, 'base64' ); //创建文件 Apis.Util.File.create( _file_path, _file_data_buffer ); // _result.push( { name : filename, encoding : encoding, mimetype : mimetype, path : _file_path } ); } } ); } ); /** multipart formdata 接受完毕,构造并返回 */ busboy.on( 'finish', function () { //Apis.Util.Base.log( _result, 'Parse form complete' ); resolve( _result ); } ); } ); }, /** * 生成输出配置 * @param requestData */ buildResponseConfig : async function ( requestData ) { let _result = { output_type : 'call', output_format : 'json', output_style : 'apis', }; //类型,请求是来自函数call还是来自gateway if ( this.checkRequestIsApiGateway( requestData.header ) ) { _result.output_type = 'gateway'; } //格式 if ( requestData.all.hasOwnProperty( 'output_format' ) ) { _result.output_format = requestData.all.output_format; } //样式 if ( requestData.all.hasOwnProperty( 'output_style' ) ) { _result.output_style = requestData.all.output_style; } //加密 if ( CONFIG[ 'Base' ].response.encrypt.enable ) { _result.output_encrypt = CONFIG[ 'Base' ].response.encrypt; } return _result; }, /** * 输出 * @param status * @param data * @param message * @param options * @returns {{isBase64Encoded: boolean, headers: *, body: *, statusCode: number}|*} */ getResponseData : function ( status = 'f', data = null, message = 'done', options = {} ) { //**********************************************************/ // 变量 //**********************************************************/ // let _result; //**********************************************************/ // 状态 //**********************************************************/ if ( Apis.Util.Base.checkSuccess( status ) ) { status = 'success'; } else { status = 'failure'; } //**********************************************************/ // headers //**********************************************************/ let _output_headers = JSON.parse( JSON.stringify( CONFIG[ 'Base' ].response.headers ) ); if ( options.hasOwnProperty( 'output_headers' ) ) { _output_headers = Object.assign( _output_headers, options.output_headers ); } //**********************************************************/ // cookie //**********************************************************/ if ( HelperCookie.data.length >= 1 ) { //赋值 _output_headers[ 'set-cookie' ] = HelperCookie.data; //恢复初始化,设置空 HelperCookie.data = []; } //**********************************************************/ // 格式 //**********************************************************/ switch ( options.output_format ) { case 'json': // _output_headers[ 'content-type' ] = 'application/json;charset=utf-8'; // if ( 'yida_gateway' === options.output_style ) { //阿里宜搭(网关)格式 _result = this._getResponseDataStyleByYiDaGateway( status, data, message ); } else if ( 'yida_options' === options.output_style ) { //阿里宜搭(选项)格式 _result = this._getResponseDataStyleByYiDaOptions( status, data, message ); } else if ( 'suda_search' === options.output_style ) { //百度速搭(search)格式 _result = this._getResponseDataStyleBySuDaGateway( status, data, message ); } else if ( 'suda_options' === options.output_style ) { //百度速搭(选项)格式 _result = this._getResponseDataStyleBySuDaOptions( status, data, message ); } else if ( 'miniui_options' === options.output_style ) { //miniui(选项)格式 _result = this._getResponseDataStyleByMiniUIOptions( status, data, message ); } else { //默认格式 _result = this._getResponseDataStyleByApis( status, data, message, options ); } _result = JSON.stringify( _result ); break; case 'html': _output_headers[ 'content-type' ] = 'text/html;charset=utf-8'; _result = data; break; case 'text': _output_headers[ 'content-type' ] = 'text/plain'; _result = data; break; default: break; } //**********************************************************/ // 返回 //**********************************************************/ if ( 'gateway' === options.output_type ) { let _status_code = (_output_headers.hasOwnProperty( 'Location' ) || _output_headers.hasOwnProperty( 'location' )) ? 301 : 200; return { 'isBase64Encoded' : false, 'statusCode' : _status_code, 'headers' : _output_headers, 'body' : _result } } else { return _result; } }, _getResponseDataStyleByYiDaGateway : function ( status, data, message ) { //阿里宜搭(网关)格式 let _result = {}; if ( status === 'success' ) { _result.success = true; _result.content = data; _result.errorCode = ''; _result.errorMsg = message; } else { _result.success = false; _result.content = false; _result.errorCode = ''; _result.errorMsg = message; } return _result; }, _getResponseDataStyleByYiDaOptions : function ( status, data, message ) { let _result = {}; let _options_data = []; if ( 'success' === status ) { //循环处理 for ( let key in data ) { if ( !data.hasOwnProperty( key ) ) { continue; } //默认值 if ( data[ key ].hasOwnProperty( 'default' ) ) { if ( data[ key ].default === true ) { data[ key ].defaultChecked = true; } //删除原始属性 delete data[ key ].default; } } //对象转数组 _options_data = Apis.Util.ArrayObject.objectToArray( data ); // _result.success = true; _result.content = { options : _options_data }; _result.errorCode = ''; _result.errorMsg = message; } else { _result.success = false; _result.content = { options : _options_data }; _result.errorCode = ''; _result.errorMsg = message; } return _result; }, _getResponseDataStyleBySuDaGateway : function ( status, data, message ) { let _result = {}; if ( status === 'success' ) { _result.status = 0; _result.msg = message; _result.data = data; } else { _result.status = -1; _result.msg = message; _result.data = {}; } return _result; }, _getResponseDataStyleBySuDaOptions : function ( status, data, message ) { let _result = {}; let _options_data = []; if ( 'success' === status ) { //循环处理 for ( let key in data ) { if ( !data.hasOwnProperty( key ) ) { continue; } //text换成label data[ key ].label = data[ key ].text; delete data[ key ].text; } //对象转数组 _options_data = Apis.Util.ArrayObject.objectToArray( data ); // _result.status = 0; _result.data = { options : _options_data }; _result.msg = message; } else { _result.status = -1; _result.data = { options : [] }; _result.msg = message; } return _result; }, _getResponseDataStyleByMiniUIOptions : function ( status, data, message ) { let _result = {}; if ( 'success' === status ) { //循环处理 for ( let key in data ) { if ( !data.hasOwnProperty( key ) ) { continue; } //追加 data[ key ].id = data[ key ].value; } // _result.status = status; _result.result = Apis.Util.ArrayObject.objectToArray( data ); _result.message = message; } else { _result.status = status; _result.result = null; _result.message = message; } return _result; }, _getResponseDataStyleByApis : function ( status, data, message, options ) { let _result = { status : status, result : data, message : message }; //固定result的值 if ( Apis.Util.Base.isEmpty( _result.result, false ) ) { _result.result = null; } //是否加密 if ( options.hasOwnProperty( 'output_encrypt' ) && options.output_encrypt.enable === true ) { _result.result = Apis.Util.Security.encrypt( options.output_encrypt.method, JSON.stringify( data ), options.output_encrypt.config[ options.output_encrypt.method ].key, options.output_encrypt.config[ options.output_encrypt.method ] ); } // return _result; }, /** * 判断请求是否是通过网关来的 * @param data * @returns {boolean} */ checkRequestIsApiGateway : function ( data ) { // 包含requestsource=APIGW说明是从api来的请求 return data.hasOwnProperty( 'requestsource' ) && data.requestsource === 'APIGW'; }, /** * 替换模板 * @param data 模板变量对象 * @param path 模板html * @returns {string} */ renderTemplate : function ( data, path ) { // 渲染 let _render_data = ArtTemplate( path, data ); // 压缩 return Minify.minify( _render_data, { //是否去掉注释 removeComments : true, //是否去掉空格 collapseWhitespace : true, //是否压缩html里的js minifyJS : true, //是否压缩html里的css minifyCSS : true } ); } }; const HelperOptions = { /** * 获取配置对象默认值 * @param objectData * @returns {*|string} */ getOptionsDefaultValue : function ( objectData ) { return Apis.Util.ArrayObject.findObjectAttributeValueByAttributeValue( objectData, 'default', true, 'value' ); }, /** * 判断值是否在配置数据中 * @param objectData * @param value * @param field * @returns {boolean} */ checkValueInOptions : function ( objectData, value, field ) { let _field = arguments[ 2 ] ? arguments[ 2 ] : 'value'; for ( let key in objectData ) { if ( !objectData.hasOwnProperty( key ) ) { continue; } if ( objectData[ key ].hasOwnProperty( 'disabled' ) && objectData[ key ][ 'disabled' ] === true ) { continue; } if ( objectData[ key ].hasOwnProperty( _field ) && (objectData[ key ][ _field ]).toString() === value.toString() ) { return true; } } return false; }, /** * 获取配置某个属性的所有值array * @param objectData * @param field * @returns {[]} */ getOptionsAllValueArray : function ( objectData, field ) { let _field = arguments[ 1 ] ? arguments[ 1 ] : 'value'; let _result = []; for ( let key in objectData ) { if ( !objectData.hasOwnProperty( key ) ) { continue; } if ( objectData[ key ].hasOwnProperty( 'disabled' ) && objectData[ key ][ 'disabled' ] === true ) { continue; } if ( objectData[ key ].hasOwnProperty( _field ) ) { _result.push( objectData[ key ][ _field ] ); } } return _result; }, /** * 获取配置某个属性的所有值list * @param objectData * @param field * @param split * @returns {string} */ getOptionsAllValueList : function ( objectData, field, split ) { let _field = arguments[ 1 ] ? arguments[ 1 ] : 'value'; let _split = arguments[ 2 ] ? arguments[ 2 ] : ','; let _result = this.getOptionsAllValueArray( objectData, _field ); return _result.join( _split ); } }; const HelperCache = { instance : null, connect : async function () { if ( this.instance === null ) { let _type = CONFIG[ 'Base' ].cache.default; let _config = CONFIG[ 'Base' ].cache[ _type ]; this.instance = new Redis( _config ); } return this; }, set : async function ( cacheKey, cacheData, cacheTime = 0 ) { //10年 let _time = (3600 * 24 * 365 * 10); if ( Number( cacheTime ) > 0 ) { _time = Number( cacheTime ); } await this.connect(); return await this.instance.set( cacheKey, JSON.stringify( cacheData ), 'EX', _time ); }, get : async function ( cacheKey ) { let _result = null; await this.connect(); await this.instance.get( cacheKey, ( err, res ) => { if ( err ) { _result = null; } else { _result = JSON.parse( res ); } } ); return _result; }, delete : async function ( cacheKey ) { let _result = false; await this.connect(); await this.instance.del( cacheKey, ( err, res ) => { if ( err ) { _result = false; } else { _result = true; } } ); return _result; }, has : async function ( cacheKey ) { await this.connect(); //return await this.get( cacheKey ); return await this.instance.exists( cacheKey ); }, flush : async function () { await this.connect(); return await this.instance.flushall(); } }; module.exports = { Base : HelperBase, Cache : HelperCache, Middleware : HelperMiddleware, Options : HelperOptions, Cookie : HelperCookie };