abler-api 0.1.25 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,29 +1,33 @@
1
1
  'use strict';
2
2
 
3
- var require$$0$1 = require('crypto');
3
+ var require$$0 = require('crypto');
4
4
  var require$$1 = require('abler-util');
5
5
  var require$$2 = require('abler-db');
6
6
  var require$$3 = require('abler-net');
7
- var require$$0$2 = require('fs');
7
+ var require$$0$1 = require('fs');
8
8
  var require$$1$1 = require('path');
9
+ var require$$1$2 = require('abler-messenger');
10
+ var require$$0$2 = require('node-cron');
9
11
 
10
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
13
 
12
- var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
14
+ var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
13
15
  var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
14
16
  var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
15
17
  var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
16
- var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
18
+ var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
17
19
  var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
20
+ var require$$1__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$1$2);
21
+ var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
18
22
 
19
- const crypto = require$$0__default$1["default"];
23
+ const crypto = require$$0__default["default"];
20
24
  const ppUtil$4 = require$$1__default["default"].ppUtil;
21
25
  const {
22
26
  dbUtil,
23
27
  kvStorage
24
28
  } = require$$2__default["default"];
25
29
  const netUtil$1 = require$$3__default["default"];
26
- let conf$2, appSetting$1, err$1, dbSql;
30
+ let conf$3, appSetting$1, err$2, dbSql;
27
31
  const pnToken = "access_token",
28
32
  hnToken = pnToken,
29
33
  pnApiKey = "apiKey",
@@ -34,7 +38,7 @@ pnApiSecret = "apiSecret",
34
38
  const MD5 = ppUtil$4.MD5,
35
39
  moveProperty = ppUtil$4.moveProperty;
36
40
 
37
- class apiUtil$1 {
41
+ class apiUtil$2 {
38
42
  static debugFlag = ppUtil$4.newGuid(); //应用必须设置,否则谁也不知道是啥
39
43
 
40
44
  static testFlag = ppUtil$4.newGuid();
@@ -42,11 +46,11 @@ class apiUtil$1 {
42
46
 
43
47
  static config(appConfig, appErrCfg, appDbSql) {
44
48
  ppUtil$4.config(appConfig, appErrCfg);
45
- conf$2 = appConfig;
46
- appSetting$1 = conf$2?.appSetting;
47
- err$1 = appErrCfg, dbSql = appDbSql;
48
- apiUtil$1.debugFlag = appSetting$1?.debugFlag || apiUtil$1.debugFlag;
49
- apiUtil$1.testFlag = appSetting$1?.testFlag || apiUtil$1.testFlag; // apiUtil.apiCallRecSaver = apiCallRecSaver;
49
+ conf$3 = appConfig;
50
+ appSetting$1 = conf$3?.appSetting;
51
+ err$2 = appErrCfg, dbSql = appDbSql;
52
+ apiUtil$2.debugFlag = appSetting$1?.debugFlag || apiUtil$2.debugFlag;
53
+ apiUtil$2.testFlag = appSetting$1?.testFlag || apiUtil$2.testFlag; // apiUtil.apiCallRecSaver = apiCallRecSaver;
50
54
  } //#region ===== 需要应用系统重写的方法
51
55
 
52
56
  /**
@@ -134,7 +138,7 @@ class apiUtil$1 {
134
138
  req._requestParams = Object.assign(req.params, req._requestParams);
135
139
  }
136
140
 
137
- apiUtil$1.setParamsFunctions(req._requestParams);
141
+ apiUtil$2.setParamsFunctions(req._requestParams);
138
142
  }
139
143
 
140
144
  return req._requestParams;
@@ -145,11 +149,11 @@ class apiUtil$1 {
145
149
  return req.tokenData;
146
150
  }
147
151
 
148
- let params = apiUtil$1.extractParams(req);
152
+ let params = apiUtil$2.extractParams(req);
149
153
  let tokenData = {
150
154
  apiKey: req.headers[hnApiKey] || params[pnApiKey],
151
155
  apiSecret: req.headers[hnApiSecret] || params[pnApiSecret],
152
- clientIp: apiUtil$1.getClientIp(req)
156
+ clientIp: apiUtil$2.getClientIp(req)
153
157
  };
154
158
  return tokenData;
155
159
  }
@@ -166,7 +170,7 @@ class apiUtil$1 {
166
170
  let result = +this[name];
167
171
 
168
172
  if (typeof result !== "number" || result < minValue || result > maxValue) {
169
- throw [err$1.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
173
+ throw [err$2.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
170
174
  }
171
175
 
172
176
  return result;
@@ -236,7 +240,7 @@ class apiUtil$1 {
236
240
 
237
241
  static apiFail(error, req) {
238
242
  configNeeded();
239
- let response = err$1.ERROR(error, err$1.errorLangParamFlag + ppUtil$4.getMsgLang(req));
243
+ let response = err$2.ERROR(error, err$2.errorLangParamFlag + ppUtil$4.getMsgLang(req));
240
244
  response.datetime = new Date();
241
245
 
242
246
  if (req && req.headers) {
@@ -258,8 +262,8 @@ class apiUtil$1 {
258
262
 
259
263
 
260
264
  static spoApiSucc(data, req) {
261
- let params = apiUtil$1.extractParams(req);
262
- return apiUtil$1.apiSuccess(data, req, params.spOrderNum);
265
+ let params = apiUtil$2.extractParams(req);
266
+ return apiUtil$2.apiSuccess(data, req, params.spOrderNum);
263
267
  }
264
268
  /**
265
269
  * 生成面向服务商的API失败返回结果
@@ -270,8 +274,8 @@ class apiUtil$1 {
270
274
 
271
275
 
272
276
  static spoApiFail(error, req) {
273
- let params = apiUtil$1.extractParams(req);
274
- return apiUtil$1.apiFail(error, req, params.spOrderNum);
277
+ let params = apiUtil$2.extractParams(req);
278
+ return apiUtil$2.apiFail(error, req, params.spOrderNum);
275
279
  }
276
280
  /**
277
281
  * API 服务结束,发送响应
@@ -308,10 +312,10 @@ class apiUtil$1 {
308
312
  static async responseOf(response, promise) {
309
313
  promise.then(function (data) {
310
314
  // console.log('RES:', apiSuccess(data));
311
- if (!response.finished) response.send(apiUtil$1.apiSuccess(data, response.req));
315
+ if (!response.finished) response.send(apiUtil$2.apiSuccess(data, response.req));
312
316
  }, function (error) {
313
317
  console.log('ERROR:', error);
314
- if (!response.finished) response.send(apiUtil$1.apiFail(error, response.req));
318
+ if (!response.finished) response.send(apiUtil$2.apiFail(error, response.req));
315
319
  });
316
320
  }
317
321
  /**
@@ -323,16 +327,16 @@ class apiUtil$1 {
323
327
 
324
328
  static async spoApiResponse(response, promise) {
325
329
  promise.then(function (result) {
326
- let responseData = apiUtil$1.spoApiSucc(result, response.req);
330
+ let responseData = apiUtil$2.spoApiSucc(result, response.req);
327
331
 
328
- apiUtil$1._saveApiCallRec(response.req.apiCallRec, responseData);
332
+ apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
329
333
 
330
334
  if (!response.finished) response.send(responseData);
331
335
  }, function (error) {
332
336
  console.log('ERROR:', error);
333
- let responseData = apiUtil$1.spoApiFail(error, response.req);
337
+ let responseData = apiUtil$2.spoApiFail(error, response.req);
334
338
 
335
- apiUtil$1._saveApiCallRec(response.req.apiCallRec, responseData);
339
+ apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
336
340
 
337
341
  if (!response.finished) response.send(responseData);
338
342
  });
@@ -349,7 +353,7 @@ class apiUtil$1 {
349
353
  req.headers.timestamp = new Date().valueOf(); // let options = {replacements: {}};
350
354
 
351
355
  let options = {};
352
- let parameters = apiUtil$1.extractParams(req);
356
+ let parameters = apiUtil$2.extractParams(req);
353
357
 
354
358
  for (let qryParam in parameters) {
355
359
  if (qryParam !== 'token') {
@@ -381,7 +385,7 @@ class apiUtil$1 {
381
385
  // }
382
386
 
383
387
  options.userInfo = req.userInfo;
384
- return apiUtil$1.setOptionsPropFuncions(options, res);
388
+ return apiUtil$2.setOptionsPropFuncions(options, res);
385
389
  }
386
390
  /**
387
391
  * 为API请求 options 设置属性
@@ -446,7 +450,7 @@ class apiUtil$1 {
446
450
  let token = req.headers[hnToken] || req.headers['x-access-token']; //向后兼容
447
451
 
448
452
  if (!token) {
449
- let params = apiUtil$1.extractParams(req);
453
+ let params = apiUtil$2.extractParams(req);
450
454
  token = params[pnToken];
451
455
 
452
456
  if (token) {
@@ -457,12 +461,12 @@ class apiUtil$1 {
457
461
  delete params.token;
458
462
  } else {
459
463
  // 如果没有token,则返回错误
460
- console.log(err$1.TOKEN_NEEDED);
464
+ console.log(err$2.TOKEN_NEEDED);
461
465
 
462
466
  if (res) {
463
- res.send(err$1.ERROR(err$1.TOKEN_NEEDED));
467
+ res.send(err$2.ERROR(err$2.TOKEN_NEEDED));
464
468
  } else if (!noErr) {
465
- throw err$1.TOKEN_NEEDED;
469
+ throw err$2.TOKEN_NEEDED;
466
470
  }
467
471
  }
468
472
  }
@@ -481,8 +485,8 @@ class apiUtil$1 {
481
485
 
482
486
  static async checkInternalToken(req) {
483
487
  // return await checkInternalToken(req);
484
- const params = apiUtil$1.extractParams(req);
485
- req.accessToken = req.accessToken || apiUtil$1.extractToken(req);
488
+ const params = apiUtil$2.extractParams(req);
489
+ req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
486
490
 
487
491
  if (req.accessToken === MD5(ppUtil$4.idNumDisturbing)) {
488
492
  //todo: 检查IP
@@ -505,7 +509,7 @@ class apiUtil$1 {
505
509
  return true;
506
510
  } else {
507
511
  // console.log('token error.', req.accessToken);
508
- throw err$1.TOKEN_INVALID;
512
+ throw err$2.TOKEN_INVALID;
509
513
  }
510
514
  }
511
515
  /**
@@ -516,16 +520,16 @@ class apiUtil$1 {
516
520
 
517
521
 
518
522
  static async checkRequestToken(req) {
519
- req.accessToken = req.accessToken || apiUtil$1.extractToken(req);
520
- const tokenKey = apiUtil$1.userTokenStoreKey(req.accessToken);
521
- const expireTime = apiUtil$1.tokenExpireTime(req);
522
- return await apiUtil$1.restoreTokenData(tokenKey, expireTime).then(async function (data) {
523
- req.userInfo = apiUtil$1.setUserIdNo(data, data._idNo);
523
+ req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
524
+ const tokenKey = apiUtil$2.userTokenStoreKey(req.accessToken);
525
+ const expireTime = apiUtil$2.tokenExpireTime(req);
526
+ return await apiUtil$2.restoreTokenData(tokenKey, expireTime).then(async function (data) {
527
+ req.userInfo = apiUtil$2.setUserIdNo(data, data._idNo);
524
528
  if (req.tokenValidater) await req.tokenValidater(req.userInfo, req);
525
529
  return true;
526
530
  }, async function (e) {
527
531
  // 如果给定的token不存在,看看是不是平台内部调用
528
- return await apiUtil$1.checkInternalToken(req);
532
+ return await apiUtil$2.checkInternalToken(req);
529
533
  });
530
534
  }
531
535
  /**
@@ -537,7 +541,7 @@ class apiUtil$1 {
537
541
 
538
542
  static isDebugMode(req) {
539
543
  if (req.__debug__ === undefined) {
540
- let dbgToken = req.headers['__debug__'] || req.headers[apiUtil$1.debugFlag];
544
+ let dbgToken = req.headers['__debug__'] || req.headers[apiUtil$2.debugFlag];
541
545
 
542
546
  if (dbgToken) {
543
547
  let envId = process.env.ECS_DEPLOY_ID;
@@ -559,11 +563,11 @@ class apiUtil$1 {
559
563
 
560
564
  static isTestMode(req) {
561
565
  if (req.__postman__ === undefined) {
562
- let dbgToken = req.headers["__postman__"] || req.headers[apiUtil$1.testFlag];
566
+ let dbgToken = req.headers["__postman__"] || req.headers[apiUtil$2.testFlag];
563
567
 
564
568
  if (dbgToken) {
565
569
  let envId = process.env.ECS_DEPLOY_ID;
566
- let testToken = MD5(req.headers.timestamp, apiUtil$1.extractToken(req, null, true) || req.headers.apikey);
570
+ let testToken = MD5(req.headers.timestamp, apiUtil$2.extractToken(req, null, true) || req.headers.apikey);
567
571
  req.__postman__ = dbgToken === testToken && (envId.indexOf("myfacesign.com") < 0 || envId.indexOf(".dev.") > 0);
568
572
  } else {
569
573
  req.__postman__ = false;
@@ -580,7 +584,7 @@ class apiUtil$1 {
580
584
 
581
585
 
582
586
  static tokenExpireTime(req) {
583
- return apiUtil$1.isDebugMode(req) ? 30 * 24 * 60 * 60 : apiUtil$1.isTestMode(req) ? 4 * 60 * 60 : appSetting$1.tokenExpireTime;
587
+ return apiUtil$2.isDebugMode(req) ? 30 * 24 * 60 * 60 : apiUtil$2.isTestMode(req) ? 4 * 60 * 60 : appSetting$1.tokenExpireTime;
584
588
  }
585
589
  /**
586
590
  * 获取用户令牌保存键
@@ -623,7 +627,7 @@ class apiUtil$1 {
623
627
  static setUserIdNo(userInfo, idNum) {
624
628
  if (userInfo && idNum) {
625
629
  userInfo._idNo = idNum;
626
- userInfo.isHKIC = apiUtil$1.checkIsHKIC(idNum);
630
+ userInfo.isHKIC = apiUtil$2.checkIsHKIC(idNum);
627
631
  }
628
632
 
629
633
  return userInfo;
@@ -640,7 +644,7 @@ class apiUtil$1 {
640
644
 
641
645
  static async storeToken(token, tokenData, dataId, req) {
642
646
  // let timeout = tokenData.clientIp.substring(0, 8) == "192.168." ? 90 * 24 : 1;
643
- let timeout = apiUtil$1.tokenExpireTime(req);
647
+ let timeout = apiUtil$2.tokenExpireTime(req);
644
648
 
645
649
  if (req.certPublicKey) {
646
650
  tokenData.certPublicKey = req.certPublicKey;
@@ -788,7 +792,7 @@ class apiUtil$1 {
788
792
  return certInfo;
789
793
  }).catch(e => {
790
794
  console.log('获取企业证书失败:\n', e);
791
- throw [err$1.ACCESS_REFUSED, `获取企业证书失败:${err$1.ERROR(e).message}`];
795
+ throw [err$2.ACCESS_REFUSED, `获取企业证书失败:${err$2.ERROR(e).message}`];
792
796
  });
793
797
  }
794
798
  /**
@@ -802,27 +806,27 @@ class apiUtil$1 {
802
806
  static async verifyApiSignature(tokenData, req) {
803
807
  try {
804
808
  if (!req.headers.timestamp) {
805
- throw [err$1.ACCESS_REFUSED, `必须在请求头中设置时戳`];
809
+ throw [err$2.ACCESS_REFUSED, `必须在请求头中设置时戳`];
806
810
  }
807
811
 
808
812
  let timestamp = parseInt(req.headers.timestamp);
809
813
  let currentTime = new Date().valueOf();
810
- let maxTimeDiff = apiUtil$1.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$1.isTestMode(req) ? 4 * 3600 : 100; // 100
814
+ let maxTimeDiff = apiUtil$2.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$2.isTestMode(req) ? 4 * 3600 : 100; // 100
811
815
 
812
816
  if (timestamp.toString() == "NaN" || currentTime < timestamp - 5000 || currentTime - timestamp > maxTimeDiff * 1000) {
813
- throw [err$1.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
817
+ throw [err$2.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
814
818
  }
815
819
 
816
820
  let signature = req.headers.signature;
817
821
 
818
822
  if (!signature) {
819
- throw [err$1.ACCESS_REFUSED, `必须在请求头中提供签名`];
823
+ throw [err$2.ACCESS_REFUSED, `必须在请求头中提供签名`];
820
824
  }
821
825
 
822
- let signData = apiUtil$1.extractToken(req, null, true) || tokenData.apiKey;
826
+ let signData = apiUtil$2.extractToken(req, null, true) || tokenData.apiKey;
823
827
  signData += timestamp;
824
828
 
825
- if (apiUtil$1.isDebugMode(req) || apiUtil$1.isTestMode(req)) {
829
+ if (apiUtil$2.isDebugMode(req) || apiUtil$2.isTestMode(req)) {
826
830
  let publicKey = req.headers.publickey || req.body.publicKey || req.query.publicKey;
827
831
 
828
832
  if (publicKey) {
@@ -837,16 +841,16 @@ class apiUtil$1 {
837
841
  return await verifyResult;
838
842
  }
839
843
 
840
- return apiUtil$1.getCompanyCertificate(tokenData.apiKey).then(info => {
844
+ return apiUtil$2.getCompanyCertificate(tokenData.apiKey).then(info => {
841
845
  tokenData.certPublicKey = info.certLiving;
842
846
  tokenData.certPublicKeySpare = info.certSpare;
843
847
  tokenData.certLivingId = info.certLivingId;
844
848
  tokenData.certSpareId = info.certSpareId;
845
849
  req.certPublicKey = info.certLiving;
846
- let token = apiUtil$1.extractToken(req, null, true);
850
+ let token = apiUtil$2.extractToken(req, null, true);
847
851
 
848
852
  if (token) {
849
- apiUtil$1.storeToken(apiUtil$1.apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
853
+ apiUtil$2.storeToken(apiUtil$2.apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
850
854
  }
851
855
  }).then(() => {
852
856
  return doVerify(signData, signature, tokenData.certPublicKey);
@@ -871,7 +875,7 @@ class apiUtil$1 {
871
875
 
872
876
  if (!tokenData.certPublicKeySpare) {
873
877
  throw {
874
- eo: err$1.ACCESS_REFUSED,
878
+ eo: err$2.ACCESS_REFUSED,
875
879
  msgArgv: "签名验证异常",
876
880
  data: e
877
881
  };
@@ -908,10 +912,10 @@ class apiUtil$1 {
908
912
  delete tokenData.certLivingId;
909
913
  delete tokenData.certSpareId;
910
914
  delete tokenData.certPublicKeySpare;
911
- let token = apiUtil$1.extractToken(req);
915
+ let token = apiUtil$2.extractToken(req);
912
916
 
913
917
  if (token) {
914
- apiUtil$1.storeToken(apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
918
+ apiUtil$2.storeToken(apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
915
919
  }
916
920
 
917
921
  console.log(`公司(${tokenData.apiKey})备用证书成功转换为正式证书`);
@@ -920,7 +924,7 @@ class apiUtil$1 {
920
924
  } catch (e) {
921
925
  console.log("SPO服务签名验证异常(备用证书), ", e);
922
926
  throw {
923
- eo: err$1.ACCESS_REFUSED,
927
+ eo: err$2.ACCESS_REFUSED,
924
928
  msgArgv: "签名验证异常(spare)",
925
929
  data: e
926
930
  };
@@ -929,7 +933,7 @@ class apiUtil$1 {
929
933
 
930
934
  if (!verifyOK) {
931
935
  console.log("SPO服务签名验证失败, tokenData: ", tokenData);
932
- throw [err$1.ACCESS_REFUSED, "签名验证未通过"];
936
+ throw [err$2.ACCESS_REFUSED, "签名验证未通过"];
933
937
  }
934
938
 
935
939
  return verifyOK;
@@ -945,32 +949,32 @@ class apiUtil$1 {
945
949
 
946
950
  static async checkApiCallValid(tokenData, req) {
947
951
  if (!tokenData.companyInfo) {
948
- tokenData.companyInfo = await apiUtil$1.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
952
+ tokenData.companyInfo = await apiUtil$2.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
949
953
  console.log("执行企业信息查询发生异常", e);
950
- throw [err$1.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
954
+ throw [err$2.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
951
955
  });
952
956
  }
953
957
 
954
958
  const companyInfo = tokenData.companyInfo;
955
959
 
956
960
  if (companyInfo != null) {
957
- let secret = apiUtil$1._getApiSecret(tokenData.apiKey);
961
+ let secret = apiUtil$2._getApiSecret(tokenData.apiKey);
958
962
 
959
- if (secret !== tokenData.apiSecret) throw err$1.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
963
+ if (secret !== tokenData.apiSecret) throw err$2.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
960
964
  // console.log("fromIp:", tokenData.clientIp, "ipWhiteList:", companyInfo.ipWhiteList);
961
965
  // let whiteList = companyInfo.ipWhiteList || "";
962
966
  // // 没有设置ip白名单的就不检查了
963
967
  // if (whiteList == "" || ipMatched(tokenData.clientIp, whiteList + ",127.0.0.1,1"))
964
968
 
965
- if (apiUtil$1.signatureVerified()) return companyInfo;
966
- return apiUtil$1.verifyApiSignature(tokenData, req).then(x => {
969
+ if (apiUtil$2.signatureVerified()) return companyInfo;
970
+ return apiUtil$2.verifyApiSignature(tokenData, req).then(x => {
967
971
  return companyInfo;
968
972
  }, e => {
969
973
  throw e;
970
974
  });
971
975
  }
972
976
 
973
- throw [err$1.API_KEY_INVALID, tokenData.apiKey];
977
+ throw [err$2.API_KEY_INVALID, tokenData.apiKey];
974
978
  }
975
979
  /**
976
980
  * 检查令牌数据是否存在
@@ -1021,7 +1025,7 @@ class apiUtil$1 {
1021
1025
  paramExists = typeof params[paramName] != 'undefined' || typeof params[paramName + paramSufix] != 'undefined';
1022
1026
  }
1023
1027
 
1024
- if (!paramExists) return ppUtil$4.errorPormise(err$1.ERROR(err$1.PARAMETER_NEEDED, paramName));
1028
+ if (!paramExists) return ppUtil$4.errorPormise(err$2.ERROR(err$2.PARAMETER_NEEDED, paramName));
1025
1029
  }
1026
1030
 
1027
1031
  return Promise.resolve(paramSufix);
@@ -1069,7 +1073,7 @@ class apiUtil$1 {
1069
1073
 
1070
1074
 
1071
1075
  static async hostIsMySelf(host, req) {
1072
- let clientIp = apiUtil$1.getClientIp(req);
1076
+ let clientIp = apiUtil$2.getClientIp(req);
1073
1077
  return ppUtil$4.getMyIp({
1074
1078
  hosts: [host, clientIp]
1075
1079
  });
@@ -1084,13 +1088,13 @@ class apiUtil$1 {
1084
1088
  static async checkForwardsHost(options) {
1085
1089
  configNeeded();
1086
1090
  const params = options.replacements;
1087
- const myEnvHosts = apiUtil$1.getEnvHosts(params);
1091
+ const myEnvHosts = apiUtil$2.getEnvHosts(params);
1088
1092
  const myIp = ppUtil$4.getMyIp();
1089
1093
  const host = params.host || myIp;
1090
- if (!myEnvHosts.hosts.contains(host)) throw [err$1.ACCESS_REFUSED, `环境${conf$2.envId}貌似无此主机:${params.host}`];
1094
+ if (!myEnvHosts.hosts.contains(host)) throw [err$2.ACCESS_REFUSED, `环境${conf$3.envId}貌似无此主机:${params.host}`];
1091
1095
 
1092
- if (!apiUtil$1.hostIsMySelf(host, options._res.req)) {
1093
- let result = await apiUtil$1.forwardsTo(host, myEnvHosts.port, params, options._res.req, myIp);
1096
+ if (!apiUtil$2.hostIsMySelf(host, options._res.req)) {
1097
+ let result = await apiUtil$2.forwardsTo(host, myEnvHosts.port, params, options._res.req, myIp);
1094
1098
 
1095
1099
  options._res.send(result);
1096
1100
 
@@ -1126,7 +1130,7 @@ class apiUtil$1 {
1126
1130
 
1127
1131
  if (result.status !== 200) {
1128
1132
  console.log(`访问 ${reqOptions.url} 出错`, result.status, result.res.statusMessage);
1129
- throw [err$1.EXCEPTION, `[${result.status}] - ${result.res.statusMessage}`];
1133
+ throw [err$2.EXCEPTION, `[${result.status}] - ${result.res.statusMessage}`];
1130
1134
  }
1131
1135
 
1132
1136
  return result.data;
@@ -1142,7 +1146,7 @@ class apiUtil$1 {
1142
1146
  let keys = Array.isArray(keyPath) ? keyPath : keyPath.split(".");
1143
1147
  let parentKey = "";
1144
1148
  let key = "config";
1145
- let value = conf$2;
1149
+ let value = conf$3;
1146
1150
  let parent = null;
1147
1151
 
1148
1152
  for (let i = 0; i < keys.length; i++) {
@@ -1152,7 +1156,7 @@ class apiUtil$1 {
1152
1156
  value = parent[key];
1153
1157
 
1154
1158
  if (value === undefined) {
1155
- throw [err$1.INVALID_PARAM, `无此配置项: ${key}`];
1159
+ throw [err$2.INVALID_PARAM, `无此配置项: ${key}`];
1156
1160
  }
1157
1161
  }
1158
1162
 
@@ -1172,10 +1176,10 @@ class apiUtil$1 {
1172
1176
 
1173
1177
  static async $checkToken(req, res, next) {
1174
1178
  try {
1175
- await apiUtil$1.checkRequestToken(req);
1179
+ await apiUtil$2.checkRequestToken(req);
1176
1180
  await next();
1177
1181
  } catch (e) {
1178
- res.send(err$1.ERROR(e));
1182
+ res.send(err$2.ERROR(e));
1179
1183
  }
1180
1184
 
1181
1185
  return false;
@@ -1192,7 +1196,7 @@ class apiUtil$1 {
1192
1196
  let token = req.headers["access_token"] || req.headers['x-access-token']; //向后兼容
1193
1197
 
1194
1198
  if (!token) {
1195
- let params = apiUtil$1.extractParams(req);
1199
+ let params = apiUtil$2.extractParams(req);
1196
1200
  token = params["access_token"];
1197
1201
 
1198
1202
  if (token) {
@@ -1215,15 +1219,15 @@ class apiUtil$1 {
1215
1219
 
1216
1220
  try {
1217
1221
  if (extractToken(req, res)) {
1218
- await apiUtil$1.restoreTokenData(apiUtil$1.userTokenStoreKey(req.accessToken), apiUtil$1.tokenExpireTime(req)).then(function (data) {
1219
- req.userInfo = apiUtil$1.setUserIdNo(data, data._idNo);
1222
+ await apiUtil$2.restoreTokenData(apiUtil$2.userTokenStoreKey(req.accessToken), apiUtil$2.tokenExpireTime(req)).then(function (data) {
1223
+ req.userInfo = apiUtil$2.setUserIdNo(data, data._idNo);
1220
1224
  }, function (e) {//no token
1221
1225
  });
1222
1226
  }
1223
1227
 
1224
1228
  return true;
1225
1229
  } catch (e) {
1226
- res.send(err$1.ERROR(e));
1230
+ res.send(err$2.ERROR(e));
1227
1231
  return false;
1228
1232
  }
1229
1233
  }
@@ -1246,7 +1250,7 @@ class apiUtil$1 {
1246
1250
  req.isMobile = true;
1247
1251
 
1248
1252
  if (!req.signatureVerified) {
1249
- let params = apiUtil$1.extractParams(req);
1253
+ let params = apiUtil$2.extractParams(req);
1250
1254
  moveProperty(params, req.headers, "access_token");
1251
1255
  moveProperty(params, req.headers, "timestamp");
1252
1256
 
@@ -1267,25 +1271,25 @@ class apiUtil$1 {
1267
1271
 
1268
1272
  static $checkApiKeyOld(req, res, next) {
1269
1273
  //检查post的信息或者url查询参数或者头信息
1270
- let tokenData = apiUtil$1.extractTokenData(req);
1271
- let params = apiUtil$1.extractParams(req);
1272
- apiUtil$1.createApiCallRec(tokenData, req);
1274
+ let tokenData = apiUtil$2.extractTokenData(req);
1275
+ let params = apiUtil$2.extractParams(req);
1276
+ apiUtil$2.createApiCallRec(tokenData, req);
1273
1277
  let errResponse = null;
1274
1278
 
1275
1279
  if (!tokenData.clientIp) {
1276
- errResponse = apiUtil$1.spoApiFail(err$1.GET_CLIENTIP_FAIL, req);
1280
+ errResponse = apiUtil$2.spoApiFail(err$2.GET_CLIENTIP_FAIL, req);
1277
1281
  } else if (!tokenData.apiKey) {
1278
- errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiKey"], req);
1282
+ errResponse = apiUtil$2.spoApiFail([err$2.PARAMETER_NEEDED, "apiKey"], req);
1279
1283
  } else if (!tokenData.apiSecret) {
1280
- errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiSecret"], req);
1284
+ errResponse = apiUtil$2.spoApiFail([err$2.PARAMETER_NEEDED, "apiSecret"], req);
1281
1285
  }
1282
1286
 
1283
1287
  if (errResponse != null) {
1284
- apiUtil$1._saveApiCallRec(req.apiCallRec, errResponse);
1288
+ apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
1285
1289
 
1286
- apiUtil$1.sendOrRedirect(req, res, errResponse);
1290
+ apiUtil$2.sendOrRedirect(req, res, errResponse);
1287
1291
  } else {
1288
- apiUtil$1.checkApiCallValid(tokenData, req).then(companyInfo => {
1292
+ apiUtil$2.checkApiCallValid(tokenData, req).then(companyInfo => {
1289
1293
  params.companyId = params.companyId || companyInfo.companyId;
1290
1294
  req.companyInfo = companyInfo;
1291
1295
  next();
@@ -1293,9 +1297,9 @@ class apiUtil$1 {
1293
1297
  console.log('apiCallInvalid:', e);
1294
1298
  let errResponse = spoApiFail(e, req);
1295
1299
 
1296
- apiUtil$1._saveApiCallRec(req.apiCallRec, errResponse);
1300
+ apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
1297
1301
 
1298
- apiUtil$1.sendOrRedirect(req, res, errResponse);
1302
+ apiUtil$2.sendOrRedirect(req, res, errResponse);
1299
1303
  });
1300
1304
  }
1301
1305
  }
@@ -1310,31 +1314,31 @@ class apiUtil$1 {
1310
1314
  return;
1311
1315
  }
1312
1316
 
1313
- let accessToken = apiUtil$1.extractToken(req);
1317
+ let accessToken = apiUtil$2.extractToken(req);
1314
1318
 
1315
1319
  if (!accessToken) {
1316
- res.send(apiUtil$1.spoApiFail(err$1.TOKEN_NEEDED, req)); // apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
1320
+ res.send(apiUtil$2.spoApiFail(err$2.TOKEN_NEEDED, req)); // apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
1317
1321
 
1318
1322
  return;
1319
1323
  }
1320
1324
 
1321
- apiUtil$1.restoreTokenData(apiUtil$1.apiTokenStoreKey(accessToken)).then(p => {
1325
+ apiUtil$2.restoreTokenData(apiUtil$2.apiTokenStoreKey(accessToken)).then(p => {
1322
1326
  // req.headers[hnApiKey] = p.apiKey || '';
1323
1327
  // req.headers[hnApiSecret] = p.apiSecret || '';
1324
1328
  if (req.isMobile) {
1325
1329
  // GET 请求的应该都是H5页面,由手机前端发起,需要把headers中的请求方ip换成服务端的
1326
1330
  // todo: 如何在API访问记录中记住请求者(手机端)的真实IP
1327
- req.headers['x-phone-ip'] = apiUtil$1.getClientIp(req);
1331
+ req.headers['x-phone-ip'] = apiUtil$2.getClientIp(req);
1328
1332
  req.headers['x-real-ip'] = p.clientIp;
1329
1333
  } else {
1330
- p.clientIp = apiUtil$1.getClientIp(req);
1334
+ p.clientIp = apiUtil$2.getClientIp(req);
1331
1335
  }
1332
1336
 
1333
1337
  req.isApiCall = true;
1334
1338
  req.tokenData = p;
1335
- return apiUtil$1.$checkApiKeyOld(req, res, next);
1339
+ return apiUtil$2.$checkApiKeyOld(req, res, next);
1336
1340
  }).catch(e => {
1337
- apiUtil$1.sendOrRedirect(req, res, apiUtil$1.spoApiFail(err$1.TOKEN_INVALID, req));
1341
+ apiUtil$2.sendOrRedirect(req, res, apiUtil$2.spoApiFail(err$2.TOKEN_INVALID, req));
1338
1342
  });
1339
1343
  }
1340
1344
  /**
@@ -1347,24 +1351,24 @@ class apiUtil$1 {
1347
1351
 
1348
1352
 
1349
1353
  static async $checkTokenOrApiKey(req, res, next) {
1350
- let accessToken = apiUtil$1.extractToken(req, res);
1354
+ let accessToken = apiUtil$2.extractToken(req, res);
1351
1355
 
1352
1356
  if (accessToken) {
1353
- let tokenExist = await apiUtil$1.tokenDataExist(apiUtil$1.userTokenStoreKey(accessToken));
1357
+ let tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.userTokenStoreKey(accessToken));
1354
1358
 
1355
1359
  if (tokenExist) {
1356
- return await apiUtil$1.$checkToken(req, res, next);
1360
+ return await apiUtil$2.$checkToken(req, res, next);
1357
1361
  }
1358
1362
 
1359
- tokenExist = await apiUtil$1.tokenDataExist(apiUtil$1.apiTokenStoreKey(accessToken));
1363
+ tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.apiTokenStoreKey(accessToken));
1360
1364
 
1361
1365
  if (tokenExist) {
1362
- return apiUtil$1.$checkApiKey(req, res, next);
1366
+ return apiUtil$2.$checkApiKey(req, res, next);
1363
1367
  } // 如果给定的token不存在,看看是不是平台内部调用
1364
1368
 
1365
1369
 
1366
- return await apiUtil$1.checkInternalToken(req).catch(e => {
1367
- res.send(apiUtil$1.apiFail(e, req));
1370
+ return await apiUtil$2.checkInternalToken(req).catch(e => {
1371
+ res.send(apiUtil$2.apiFail(e, req));
1368
1372
  return false;
1369
1373
  });
1370
1374
  }
@@ -1384,8 +1388,8 @@ class apiUtil$1 {
1384
1388
  const params = options.replacements;
1385
1389
  let item = params.item;
1386
1390
  delete params.item;
1387
- if (await apiUtil$1.checkForwardsHost(options)) return true;
1388
- let c = apiUtil$1.parseCfgPath(item);
1391
+ if (await apiUtil$2.checkForwardsHost(options)) return true;
1392
+ let c = apiUtil$2.parseCfgPath(item);
1389
1393
  delete c.parent;
1390
1394
  c.host = ppUtil$4.getMyIp();
1391
1395
  return c;
@@ -1404,11 +1408,11 @@ class apiUtil$1 {
1404
1408
  delete params.item; // if (await checkForwardsHost(options))
1405
1409
  // return true;
1406
1410
 
1407
- await apiUtil$1.parametersOK(params, "value");
1408
- let c = apiUtil$1.parseCfgPath(item);
1411
+ await apiUtil$2.parametersOK(params, "value");
1412
+ let c = apiUtil$2.parseCfgPath(item);
1409
1413
 
1410
1414
  if (typeof c.value === "object") {
1411
- throw [err$1.ACCESS_REFUSED, `暂不支持修改复杂配置`];
1415
+ throw [err$2.ACCESS_REFUSED, `暂不支持修改复杂配置`];
1412
1416
  } // c.oldValue = c.value;
1413
1417
 
1414
1418
 
@@ -1423,21 +1427,21 @@ class apiUtil$1 {
1423
1427
  }
1424
1428
 
1425
1429
  function configNeeded() {
1426
- if (!conf$2 || !err$1) {
1430
+ if (!conf$3 || !err$2) {
1427
1431
  ppUtil$4.configNeeded();
1428
- conf$2 = ppUtil$4.appConfig;
1429
- appSetting$1 = conf$2.appSetting;
1430
- err$1 = ppUtil$4.appErrCfg;
1432
+ conf$3 = ppUtil$4.appConfig;
1433
+ appSetting$1 = conf$3.appSetting;
1434
+ err$2 = ppUtil$4.appErrCfg;
1431
1435
  }
1432
1436
  }
1433
1437
 
1434
- var ppUtilApi = apiUtil$1;
1438
+ var ppUtilApi = apiUtil$2;
1435
1439
 
1436
- const fs = require$$0__default$2["default"];
1440
+ const fs = require$$0__default$1["default"];
1437
1441
  const path = require$$1__default$1["default"];
1438
1442
  const ppUtil$3 = require$$1__default["default"].ppUtil;
1439
1443
  const redisUtil = require$$2__default["default"].redisUtil;
1440
- let conf$1, err; // const dbCheck = require('../dbupdate/dd-version');
1444
+ let conf$2, err$1; // const dbCheck = require('../dbupdate/dd-version');
1441
1445
 
1442
1446
  /**
1443
1447
  * API服务启动时前置条件检查
@@ -1457,9 +1461,9 @@ class preconditions$1 {
1457
1461
 
1458
1462
  static setAppName(aName) {
1459
1463
  ppUtil$3.configNeeded();
1460
- conf$1 = ppUtil$3.appConfig;
1461
- err = ppUtil$3.appErrCfg;
1462
- preconditions$1.appName = aName || conf$1.thisApp;
1464
+ conf$2 = ppUtil$3.appConfig;
1465
+ err$1 = ppUtil$3.appErrCfg;
1466
+ preconditions$1.appName = aName || conf$2.thisApp;
1463
1467
  return preconditions$1;
1464
1468
  }
1465
1469
 
@@ -1540,20 +1544,20 @@ async function createEnvSettingFile(fileName) {
1540
1544
  try {
1541
1545
  const cfgText = await ppUtil$3.doCreateEnvSettingFile(fileName);
1542
1546
 
1543
- if (cfgText.indexOf(`cfgVersion: "${conf$1._envSetting.cfgVersion}"`) > 0) {
1547
+ if (cfgText.indexOf(`cfgVersion: "${conf$2._envSetting.cfgVersion}"`) > 0) {
1544
1548
  console.log(`\n*** 已創建新的本機環境配置文件\n${fileName}\n请檢查各項內容是否正确(此项更新服务可正常运行)\n\n`);
1545
1549
  return "";
1546
1550
  }
1547
1551
 
1548
- return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$1._envSettings.default.cfgVersion}`;
1552
+ return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$2._envSettings.default.cfgVersion}`;
1549
1553
  } catch (e) {
1550
- return `創建本機環境配置文件失敗\n《${fileName}》\n${err.ERROR(e).message}`;
1554
+ return `創建本機環境配置文件失敗\n《${fileName}》\n${err$1.ERROR(e).message}`;
1551
1555
  }
1552
1556
  }
1553
1557
 
1554
1558
  async function checkExEnvSetting(loadjs) {
1555
- if (!conf$1._envSetting.localSettingImported) {
1556
- let fileName = conf$1.getEnvSettingFileName();
1559
+ if (!conf$2._envSetting.localSettingImported) {
1560
+ let fileName = conf$2.getEnvSettingFileName();
1557
1561
 
1558
1562
  if (!fs.existsSync(fileName)) {
1559
1563
  return await createEnvSettingFile(fileName);
@@ -1561,7 +1565,7 @@ async function checkExEnvSetting(loadjs) {
1561
1565
 
1562
1566
  let envSettingEx = loadjs(fileName);
1563
1567
 
1564
- if (envSettingEx.cfgVersion !== conf$1._envSettings.default.cfgVersion) {
1568
+ if (envSettingEx.cfgVersion !== conf$2._envSettings.default.cfgVersion) {
1565
1569
  if (envSettingEx.cfgVersion !== "0.0") {
1566
1570
  let fp = path.parse(fileName);
1567
1571
  let newFileName = path.join(fp.dir, fp.name + envSettingEx.cfgVersion + fp.ext);
@@ -1580,7 +1584,7 @@ async function checkExEnvSetting(loadjs) {
1580
1584
 
1581
1585
 
1582
1586
  async function checkRedis() {
1583
- if (!conf$1.redis.enabled) return "";
1587
+ if (!conf$2.redis.enabled) return "";
1584
1588
  const redis = redisUtil.newClient("io"); // console.log(`checkRedis begin:`);
1585
1589
 
1586
1590
  await ppUtil$3.wait(15 * 1000, param => {
@@ -1601,209 +1605,393 @@ async function checkRedis() {
1601
1605
 
1602
1606
  var ppPrecond = preconditions$1;
1603
1607
 
1604
- var require$$0 = require$$2__default["default"];
1608
+ // redis 可用,则使用基于 redis 的消息订阅发布系统
1609
+ // 若 redis 不可用,则将消息转发到其它主机
1605
1610
 
1606
- function _interopDefaultLegacy$1(e) {
1607
- return e && typeof e === 'object' && 'default' in e ? e : {
1608
- 'default': e
1609
- };
1610
- }
1611
+ const {
1612
+ ppUtil: ppUtil$2
1613
+ } = require$$1__default["default"];
1614
+ const RedisMessenger = require$$1__default$2["default"];
1615
+ const {
1616
+ netUtil
1617
+ } = require$$3__default["default"];
1618
+ let conf$1;
1611
1619
 
1612
- var require$$0__default = /*#__PURE__*/_interopDefaultLegacy$1(require$$0); // const logger = require("log4js").getLogger();
1620
+ class commonMessenger$2 {
1621
+ static myMsgAddr = "";
1622
+ static redisMessenger = null;
1623
+ static onMessage = [];
1613
1624
 
1625
+ static initMessenger(appConfig, appErrCfg, msgChannel) {
1626
+ conf$1 = appConfig;
1627
+ this.redisMessenger = conf$1.redis.enabled ? new RedisMessenger(appConfig, appErrCfg, msgChannel).subscribe(msgChannel) : null;
1628
+ this.myMsgAddr = commonMessenger$2.getMyMsgAddr();
1629
+ }
1614
1630
 
1615
- const redis = require$$0__default["default"].redisUtil;
1631
+ static getMyMsgAddr() {
1632
+ if (!conf$1.myMsgAddr) {
1633
+ conf$1.pm_id = process.env.pm_id || "0";
1634
+ let myIp = ppUtil$2.getMyIp();
1616
1635
 
1617
- class Messenger {
1618
- constructor(appConfig, appErrCfg) {
1619
- if (appConfig) {
1620
- redis.config(appConfig, appErrCfg);
1621
- }
1636
+ if (this.redisMessenger) {
1637
+ myIp = `${conf$1.pm_id}@${myIp}`;
1638
+ }
1622
1639
 
1623
- this.channel = "ecs_messenger"; //default channel
1640
+ conf$1.myMsgAddr = myIp;
1641
+ console.log(`myMsgAddr: `, conf$1.myMsgAddr);
1642
+ }
1624
1643
 
1625
- this.publisher = redis.newClient("publisher");
1626
- this.subscriber = redis.newClient("subscriber");
1627
- this.subscriber.on("subscribe", function (channel, count) {
1628
- console.log("chanel subscribed :", channel, count);
1629
- });
1630
- this.subscriber.on("message", this.handleMessage);
1644
+ return conf$1.myMsgAddr;
1631
1645
  }
1632
1646
 
1633
- setMessageHandle(handle, channel) {
1634
- channel = channel || this.channel;
1635
- Messenger.onmessage = Messenger.onmessage || {};
1636
- Messenger.onmessage[channel] = Messenger.onmessage[channel] || [];
1637
- const appMsgHandles = Messenger.onmessage[channel];
1647
+ static setMessageHandle(messageHandle) {
1648
+ if (this.redisMessenger) {
1649
+ return this.redisMessenger.setMessageHandle(messageHandle, msgChannel);
1650
+ }
1638
1651
 
1639
- for (let i = 0; i < appMsgHandles.length; i++) {
1640
- if (appMsgHandles[i] === handle) return this;
1652
+ if (commonMessenger$2.onMessage.indexOf(messageHandle) < 0) {
1653
+ commonMessenger$2.onMessage.push(messageHandle);
1641
1654
  }
1642
1655
 
1643
- appMsgHandles.push(handle);
1644
- return this;
1656
+ return commonMessenger$2;
1645
1657
  }
1646
1658
 
1647
- subscribe(channel) {
1648
- channel = channel || this.channel;
1649
- this.subscriber.subscribe(channel);
1650
- return this;
1659
+ static async publishMessage(message) {
1660
+ if (this.redisMessenger) {
1661
+ return this.redisMessenger.publish(message, msgChannel);
1662
+ } else {
1663
+ //没有消息处理器,则将消息转发到目标地址(不支持pm2多进程)
1664
+ if (message.destAddr) {
1665
+ await forwardMessage(message);
1666
+ } else {
1667
+ for (let i = 0; i < conf$1.appSetting.serverHosts.length; i++) {
1668
+ message.destAddr = conf$1.appSetting.serverHosts[i];
1669
+
1670
+ if (message.destAddr !== conf$1.myMsgAddr) {
1671
+ await forwardMessage(message);
1672
+ }
1673
+ }
1674
+ }
1675
+ }
1651
1676
  }
1652
1677
 
1653
- async handleMessage(channel, message) {
1654
- console.log(`通道[${channel}]收到订阅消息:`, message);
1655
- let appMsgHandles = Messenger.onmessage[channel] || [];
1678
+ static async handleInternalMessage(options) {
1679
+ const message = options.replacements;
1656
1680
 
1657
- for (let i = 0; i < appMsgHandles.length; i++) {
1658
- const appMsgHandle = appMsgHandles[i];
1681
+ for (let i = 0; i < commonMessenger$2.onMessage.length; i++) {
1682
+ const appMsgHandle = commonMessenger$2.onMessage[i];
1659
1683
 
1660
1684
  try {
1661
- let msgObj = JSON.parse(message); // await appMsgHandle(msgObj);
1662
-
1663
- appMsgHandle(msgObj);
1685
+ await appMsgHandle(message);
1664
1686
  } catch (e) {
1665
1687
  console.log(e);
1666
1688
  }
1667
1689
  }
1668
1690
  }
1669
1691
 
1670
- async publish(message, channel) {
1671
- channel = channel || this.channel;
1672
- let msgStr = typeof message === "object" ? JSON.stringify(message) : message.toString();
1673
- console.log(`通道[${channel}]发布消息:`, message);
1674
- await this.publisher.publish(channel, msgStr);
1675
- return this;
1676
- }
1677
-
1678
1692
  }
1679
1693
 
1680
- var ppMessenger$1 = Messenger;
1681
- const ppMessenger = ppMessenger$1;
1682
- var ppUtil$2 = ppMessenger;
1683
- var ppUtil_1 = ppUtil$2;
1694
+ async function forwardMessage(message) {
1695
+ let reqOptions = {
1696
+ url: `https://${message.destAddr}:${appSetting.listenPort}/api/message`,
1697
+ method: "POST",
1698
+ data: message
1699
+ };
1700
+ let res = await netUtil.apiRequest(reqOptions).catch(e => {
1701
+ console.log(`转发消息失败, url: ${reqOptions.url}`, e);
1702
+ throw e;
1703
+ });
1704
+ return res.data;
1705
+ }
1684
1706
 
1685
- // redis 可用,则使用基于 redis 的消息订阅发布系统
1686
- // 若 redis 不可用,则将消息转发到其它主机
1707
+ var ppMessengerEx = commonMessenger$2;
1687
1708
 
1688
- const RedisMessenger = ppUtil_1;
1709
+ /**
1710
+ * CSCA 自动任务
1711
+ * ==============
1712
+ */
1713
+ const CRON = require$$0__default$2["default"];
1689
1714
  const {
1690
- netUtil
1691
- } = require$$3__default["default"];
1692
- let conf;
1715
+ ppUtil: ppUtil$1
1716
+ } = require$$1__default["default"];
1717
+ const apiUtil$1 = ppUtilApi;
1718
+ const commonMessenger$1 = ppMessengerEx;
1719
+ const MT_SCHEDULE_STATE = 'schedule-state',
1720
+ MT_SCHEDULE_STATE_REPLY = 'schedule-state-reply';
1721
+ let conf, err;
1722
+
1723
+ class schedule$1 {
1724
+ static tasks = {};
1725
+ /**
1726
+ * 注册一个计划任务
1727
+ * @param taskName
1728
+ * @param taskCaption
1729
+ * @param cronExp
1730
+ * @param taskFunc
1731
+ * @param autoStart
1732
+ * @returns {Promise<{}|{}|{cron: *, _message_: string}|any>}
1733
+ */
1693
1734
 
1694
- class noneRedisMessenger {
1695
- static onMessage = [];
1735
+ static async registerTask(taskName, taskCaption, cronExp, taskFunc, autoStart) {
1736
+ if (!conf) {
1737
+ ppUtil$1.configNeeded();
1738
+ conf = ppUtil$1.appConfig;
1739
+ err = ppUtil$1.appErrCfg;
1740
+ }
1696
1741
 
1697
- static async publishMessage(message) {
1698
- //没有消息处理器,则将消息转发到目标地址(不支持pm2多进程)
1699
- if (message.destAddr) {
1700
- await forwardMessage(message);
1701
- } else {
1702
- for (let i = 0; i < conf.appSetting.serverHosts.length; i++) {
1703
- message.destAddr = conf.appSetting.serverHosts[i];
1742
+ if (!this.envAllowed()) return {};
1743
+ let task = this.findTask(taskName);
1744
+
1745
+ if (task) {
1746
+ if (task.cronExp !== cronExp || task.taskFunc !== taskFunc) {
1747
+ this.stop(taskName);
1748
+ task = null;
1749
+ }
1750
+ }
1704
1751
 
1705
- if (message.destAddr !== conf.myMsgAddr) {
1706
- await forwardMessage(message);
1752
+ if (!task) {
1753
+ task = {
1754
+ name: taskName,
1755
+ caption: taskCaption,
1756
+ cronExp: cronExp,
1757
+ taskFunc: taskFunc,
1758
+ schedule: null,
1759
+ doScheduleTask: async function () {
1760
+ let self = this;
1761
+ if (this._pp_task) self = this._pp_task;
1762
+ console.log(new Date().format('[yyyy/MM/dd hh:mm:ss:S]'), `开始执行${self.caption}任务 ...`);
1763
+ await self.taskFunc();
1764
+ console.log(new Date().format('[yyyy/MM/dd hh:mm:ss:S]'), `${self.caption}任务执行结束`);
1707
1765
  }
1766
+ };
1767
+ this.tasks[taskName] = task;
1768
+
1769
+ if (autoStart) {
1770
+ return await this.start(task);
1708
1771
  }
1772
+
1773
+ return this.getTaskInfo(task, "任务已注册。");
1709
1774
  }
1775
+
1776
+ return this.getTaskInfo(task, "任务已存在。");
1710
1777
  }
1711
1778
 
1712
- static setMessageHandle(messageHandle) {
1713
- if (noneRedisMessenger.onMessage.indexOf(messageHandle) < 0) {
1714
- noneRedisMessenger.onMessage.push(messageHandle);
1779
+ static getTaskInfo(task, msg) {
1780
+ // return Object.assign({_message_: msg}, task);
1781
+ return {
1782
+ name: task.name,
1783
+ caption: task.caption,
1784
+ cronExp: task.cronExp,
1785
+ state: task.schedule ? "started" : "stopped",
1786
+ _message_: msg
1787
+ };
1788
+ }
1789
+ /**
1790
+ * 启动任务
1791
+ * @param taskOrName
1792
+ * @param cronExp
1793
+ * @returns {Promise<{}|{cron: *, _message_: string}>}
1794
+ */
1795
+
1796
+
1797
+ static async start(taskOrName, cronExp) {
1798
+ if (!this.envAllowed()) return {};
1799
+ let task = taskOrName;
1800
+
1801
+ if (typeof task === "string") {
1802
+ task = this.findTask(taskOrName);
1715
1803
  }
1716
1804
 
1717
- return noneRedisMessenger;
1805
+ if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
1806
+ cronExp = cronExp || task.cronExp;
1807
+
1808
+ if (task.cronExp !== cronExp) {
1809
+ this.stop(task);
1810
+ task.cronExp = cronExp;
1811
+ }
1812
+
1813
+ if (task.schedule) {
1814
+ return this.getTaskInfo(task, "任务已启动,无需重复启动。");
1815
+ }
1816
+
1817
+ task.schedule = CRON.schedule(cronExp, task.doScheduleTask);
1818
+ task.schedule._task._pp_task = task;
1819
+ return this.getTaskInfo(task, "任务已启动。");
1718
1820
  }
1821
+ /**
1822
+ * 停止任务
1823
+ * @param taskOrName
1824
+ * @returns {Promise<{}|{cron: *, _message_: string}|{_message_: string}>}
1825
+ */
1719
1826
 
1720
- static async handleInternalMessage(options) {
1721
- const message = options.replacements;
1722
1827
 
1723
- for (let i = 0; i < noneRedisMessenger.onMessage.length; i++) {
1724
- const appMsgHandle = noneRedisMessenger.onMessage[i];
1828
+ static async stop(taskOrName) {
1829
+ if (!this.envAllowed()) return {};
1830
+ let task = taskOrName;
1725
1831
 
1726
- try {
1727
- // await appMsgHandle(message);
1728
- appMsgHandle(message);
1729
- } catch (e) {
1730
- console.log(e);
1731
- }
1832
+ if (typeof task === "string") {
1833
+ task = this.findTask(taskOrName);
1732
1834
  }
1733
- }
1734
1835
 
1735
- }
1836
+ if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
1736
1837
 
1737
- class commonMessenger$1 {
1738
- static myMsgAddr = "";
1739
- static redisMessenger = null;
1838
+ if (task.schedule) {
1839
+ task.schedule.stop();
1840
+ task.schedule = null;
1841
+ return this.getTaskInfo(task, "任务已停止。");
1842
+ }
1740
1843
 
1741
- static initMessenger(appConfig, appErrCfg, msgChannel) {
1742
- conf = appConfig;
1743
- this.redisMessenger = conf.redis.enabled ? new RedisMessenger(appConfig, appErrCfg, msgChannel).subscribe(msgChannel) : null;
1744
- this.myMsgAddr = commonMessenger$1.getMyMsgAddr();
1844
+ return this.getTaskInfo(task, "任务未启动,无需停止。");
1745
1845
  }
1846
+ /**
1847
+ * 获取或设置当前状态(来自远程的API调用)
1848
+ * @param options
1849
+ * @returns {Promise<unknown>}
1850
+ */
1746
1851
 
1747
- static getMyMsgAddr() {
1748
- if (!conf.myMsgAddr) {
1749
- conf.pm_id = process.env.pm_id || "0";
1750
- let myIp = ppUtil.getMyIp();
1751
1852
 
1752
- if (this.redisMessenger) {
1753
- myIp = `${conf.pm_id}@${myIp}`;
1853
+ static async state(options) {
1854
+ const params = options.replacements; // await commonMessenger.parametersOK(params, "taskName");
1855
+
1856
+ const req = options._res.req;
1857
+
1858
+ if (req) {
1859
+ if (req.method === 'GET') {
1860
+ delete params.state;
1861
+ } else {
1862
+ await apiUtil$1.parametersOK(params, 'taskName', "state");
1754
1863
  }
1864
+ }
1755
1865
 
1756
- conf.myMsgAddr = myIp;
1757
- console.log(`myMsgAddr: `, conf.myMsgAddr);
1866
+ if (this.envAllowed()) {
1867
+ return this._state(params);
1868
+ } // 环境变量启用计划任务,但当前环境不能执行,
1869
+ // 说明收到此API请求的进程不是第一个进程,或者此前服务器不是第一台服务器,
1870
+ // 这种情况下,将此请求作为消息发布出去,
1871
+ // 第一台服务器的第一个进程收到消息后进行处理,再将结果作为消息发布,
1872
+ // 本进程收到处理结果后果作为响应发送回客户端
1873
+
1874
+
1875
+ if (process.env.SCHEDULE_ENABLED) {
1876
+ let replyId = ppUtil$1.newGuid();
1877
+ return await new Promise((resolve, reject) => {
1878
+ commonMessenger$1.setMessageHandle(message => {
1879
+ if (message._type === MT_SCHEDULE_STATE_REPLY && message.replyId === replyId) {
1880
+ replyId = '';
1881
+ resolve(message.result);
1882
+ return;
1883
+ }
1884
+
1885
+ if (message._type === MT_SCHEDULE_STATE) {
1886
+ if (schedule$1.enabled()) {
1887
+ message.result = schedule$1._state(message.params);
1888
+ message._type = MT_SCHEDULE_STATE_REPLY;
1889
+ message.destAddr = message.replyAddr;
1890
+ commonMessenger$1.publishMessage(message);
1891
+ }
1892
+ }
1893
+ });
1894
+ commonMessenger$1.publishMessage({
1895
+ _type: MT_SCHEDULE_STATE,
1896
+ replyId,
1897
+ replyAddr: conf.myMsgAddr,
1898
+ params
1899
+ }).catch(e => {
1900
+ replyId = '';
1901
+ reject(e);
1902
+ });
1903
+ setTimeout(() => {
1904
+ if (replyId) {
1905
+ reject("schedule.state: 等待处理结果超时");
1906
+ }
1907
+ }, 2 * 60 * 1000);
1908
+ });
1758
1909
  }
1759
1910
 
1760
- return conf.myMsgAddr;
1911
+ return {
1912
+ _message_: "此环境无自动任务"
1913
+ };
1761
1914
  }
1762
1915
 
1763
- static setMessageHandle(messageHandle) {
1764
- if (this.redisMessenger) {
1765
- return this.redisMessenger.setMessageHandle(messageHandle, msgChannel);
1916
+ static async _state(params) {
1917
+ let apiResult = {};
1918
+ let task;
1919
+
1920
+ if (params.taskName) {
1921
+ task = this.findTask(params.taskName);
1922
+ if (!task) throw [err.INVALID_PARAM, `任务${params.taskName}不存在`];
1766
1923
  }
1767
1924
 
1768
- return noneRedisMessenger.setMessageHandle(messageHandle);
1769
- }
1925
+ if (params.state) {
1926
+ if ("started" === params.state) {
1927
+ apiResult = await this.start(task, params.cron);
1928
+ } else if ("stopped" === params.state) {
1929
+ apiResult = await this.stop(task);
1930
+ } else {
1931
+ throw [err.INVALID_PARAM, `(${params.state}), 只能是 started/stopped`];
1932
+ }
1770
1933
 
1771
- static async publishMessage(message) {
1772
- if (this.redisMessenger) {
1773
- return this.redisMessenger.publish(message, msgChannel);
1774
- } else {
1775
- return noneRedisMessenger.publishMessage(message);
1934
+ if (params.runOnce) {
1935
+ task = this.findTask(params.taskName);
1936
+ apiResult._message_ += "\n正在手动执行任务"; // await
1937
+
1938
+ task.doScheduleTask();
1939
+ }
1940
+
1941
+ return this.getTaskInfo(task, apiResult._message_);
1942
+ }
1943
+
1944
+ if (task) {
1945
+ return this.getTaskInfo(task);
1946
+ }
1947
+
1948
+ const result = [];
1949
+
1950
+ for (let k in this.tasks) {
1951
+ result.push(this.getTaskInfo(this.tasks[k]));
1776
1952
  }
1953
+
1954
+ return result;
1777
1955
  }
1778
1956
 
1779
- static async handleInternalMessage(options) {
1780
- return await noneRedisMessenger.handleInternalMessage(options);
1957
+ static deleteTask(taskName) {
1958
+ delete this.tasks[taskName];
1781
1959
  }
1782
1960
 
1783
- }
1961
+ static findTask(taskName) {
1962
+ return this.tasks[taskName];
1963
+ }
1964
+ /**
1965
+ * 确定当前进程环境是否启用自动任务
1966
+ * @returns {Promise<void>}
1967
+ */
1968
+
1969
+
1970
+ static envAllowed() {
1971
+ let enabled = // PM2配置中指定了环境变量 SCHEDULE_ENABLED
1972
+ !!process.env.SCHEDULE_ENABLED // 如果PM2启动了多个进程,则只在第一个进程执行
1973
+ && process.env.NODE_APP_INSTANCE === '0'; // 如果有多台服务器,则只在第一台执行
1974
+
1975
+ if (enabled && conf.appSetting.serverHosts && conf.appSetting.serverHosts.length > 1) {
1976
+ enabled = conf.myMsgAddr.indexOf(conf.appSetting.serverHosts[0]) === 0;
1977
+ }
1978
+
1979
+ return enabled;
1980
+ }
1784
1981
 
1785
- async function forwardMessage(message) {
1786
- let reqOptions = {
1787
- url: `https://${message.destAddr}:${appSetting.listenPort}/api/message`,
1788
- method: "POST",
1789
- data: message
1790
- };
1791
- let res = await netUtil.apiRequest(reqOptions).catch(e => {
1792
- console.log(`转发消息失败, url: ${reqOptions.url}`, e);
1793
- throw e;
1794
- });
1795
- return res.data;
1796
1982
  }
1797
1983
 
1798
- var ppMessengerEx = commonMessenger$1;
1984
+ var ppSchedule = schedule$1;
1799
1985
 
1800
1986
  const apiUtil = ppUtilApi;
1801
1987
  const preconditions = ppPrecond;
1802
1988
  const commonMessenger = ppMessengerEx;
1803
- var ppUtil$1 = {
1989
+ const schedule = ppSchedule;
1990
+ var ppUtil = {
1804
1991
  apiUtil,
1805
1992
  preconditions,
1806
- commonMessenger
1993
+ commonMessenger,
1994
+ schedule
1807
1995
  };
1808
1996
 
1809
- module.exports = ppUtil$1;
1997
+ module.exports = ppUtil;