q-koa 13.6.4 → 13.7.0

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.
package/core/app.js CHANGED
@@ -6,7 +6,7 @@ const fs = require('fs')
6
6
  const fsPromise = require('fs/promises')
7
7
  const Sequelize = require('sequelize')
8
8
  const redis = require('redis')
9
- const moment = require('moment')
9
+ const dayjs = require('dayjs')
10
10
  const { EventEmitter } = require('events')
11
11
  const nodeVm = require('vm')
12
12
  const { LRUCache } = require('lru-cache')
@@ -241,7 +241,7 @@ class APP {
241
241
 
242
242
  if (url.length > 2 && this.config.log.request) {
243
243
  console.log(
244
- moment().format('HH:mm:ss'),
244
+ dayjs().format('HH:mm:ss'),
245
245
  url,
246
246
  host,
247
247
  ctx.request.clientType
@@ -323,7 +323,7 @@ class APP {
323
323
  }
324
324
  this.server = this.app.listen(this.port, () => {
325
325
  console.log(
326
- `${moment().format(
326
+ `${dayjs().format(
327
327
  'HH:mm:ss'
328
328
  )} server is running at http://localhost:${this.port}`
329
329
  )
@@ -923,7 +923,7 @@ class APP {
923
923
  }
924
924
  }
925
925
  }
926
- const start = moment().valueOf()
926
+ const start = dayjs().valueOf()
927
927
  for (const fn of ['service']) {
928
928
  const cloneTarget = this.app[appName][fn]
929
929
 
@@ -940,7 +940,7 @@ class APP {
940
940
  }
941
941
 
942
942
  if (is_dev) {
943
- console.log('挂载service bind', moment().valueOf() - start)
943
+ console.log('挂载service bind', dayjs().valueOf() - start)
944
944
  }
945
945
  }
946
946
 
@@ -2279,11 +2279,11 @@ APP.Random = Random
2279
2279
  APP.Validator = Validator
2280
2280
  APP.ServiceError = ServiceError
2281
2281
  APP.TransactionError = TransactionError
2282
- APP.moment = moment
2282
+ APP.dayjs = dayjs
2283
2283
  APP.utils = require('./file/utils')
2284
2284
  APP.is_dev = is_dev
2285
2285
 
2286
- global.moment = moment
2286
+ global.dayjs = dayjs
2287
2287
  global.Sequelize = Sequelize
2288
2288
  global.lodash = _
2289
2289
 
@@ -467,9 +467,9 @@ const expressFn = async ({ app, express_number: _express_number, mobile }) => {
467
467
  },
468
468
  })
469
469
  if (history) {
470
- const diffNoLong = moment().diff(moment(history.updated_at), 'hours') < 1
470
+ const diffNoLong = dayjs().diff(dayjs(history.updated_at), 'hour') < 1
471
471
  const isTooLong =
472
- moment().diff(moment(history.result.updateTime), 'days') > 30
472
+ dayjs().diff(dayjs(history.result.updateTime), 'day') > 30
473
473
 
474
474
  if (diffNoLong || isTooLong) {
475
475
  return history.result
@@ -753,7 +753,7 @@ exports.restart = async (ctx) => {
753
753
 
754
754
  const { hour: _hour } = ctx.request.query
755
755
 
756
- const hour = moment().hour()
756
+ const hour = dayjs().hour()
757
757
  if (hour === Number(_hour)) {
758
758
  pm2.connect((err) => {
759
759
  console.log(err)
@@ -1,7 +1,7 @@
1
1
  const { getConfig, ServiceError } = require('q-koa')
2
2
  const axios = require('axios')
3
3
  const XLSX = require('xlsx')
4
- const moment = require('moment')
4
+ const dayjs = require('dayjs')
5
5
 
6
6
  exports.gpt = async ({ app, content }) => {
7
7
  if (!content) throw new ServiceError('?content')
@@ -34,7 +34,7 @@ exports.gpt = async ({ app, content }) => {
34
34
  }
35
35
 
36
36
  exports.formatXLSX = ({ header, data, fileName: _fileName }) => {
37
- const fileName = `${_fileName || moment().format('YYYYMMDDHHmmss') + ''}.xlsx`
37
+ const fileName = `${_fileName || dayjs().format('YYYYMMDDHHmmss') + ''}.xlsx`
38
38
  const workbook = XLSX.utils.book_new()
39
39
  const worksheetData = [header, ...data]
40
40
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData)
@@ -1,4 +1,4 @@
1
- const { getAppByCtx, getConfig, lodash, moment, getService } = require('q-koa')
1
+ const { getAppByCtx, getConfig, lodash, dayjs, getService } = require('q-koa')
2
2
  const util = require('util')
3
3
  const axios = require('axios')
4
4
  const qr = require('qr-image')
@@ -343,7 +343,7 @@ const updateTask = async ({ app, list, active_time, douyin }) => {
343
343
  digg_count: statistics.digg_count,
344
344
  download_count: statistics.download_count,
345
345
  forward_count: statistics.forward_count,
346
- created_at: moment(create_time * 1000),
346
+ created_at: dayjs(create_time * 1000),
347
347
  is_reviewed,
348
348
  name: title,
349
349
  video_status: status[video_status],
@@ -366,7 +366,7 @@ exports.hotSearch = async (ctx) => {
366
366
 
367
367
  const hotWord = await app.model.hot_search.findOne()
368
368
  const minutes = hotWord
369
- ? moment().diff(moment(hotWord.created_at), 'minutes')
369
+ ? dayjs().diff(dayjs(hotWord.created_at), 'minute')
370
370
  : 1000
371
371
 
372
372
  if (minutes < 30) {
@@ -1,4 +1,4 @@
1
- const { Sequelize, Random, lodash, moment } = require('q-koa')
1
+ const { Sequelize, Random, lodash, dayjs } = require('q-koa')
2
2
 
3
3
  exports.name = {
4
4
  type: Sequelize.STRING(),
@@ -74,9 +74,9 @@ exports.value = {
74
74
  ? 0
75
75
  : Number(this.getDataValue('value'))
76
76
  case 'datetime':
77
- return moment(this.getDataValue('value')).format('YYYY-MM-DD HH:mm:ss')
77
+ return dayjs(this.getDataValue('value')).format('YYYY-MM-DD HH:mm:ss')
78
78
  case 'date':
79
- return moment(this.getDataValue('value')).format('YYYY-MM-DD')
79
+ return dayjs(this.getDataValue('value')).format('YYYY-MM-DD')
80
80
  case 'image':
81
81
  return this.getDataValue('value').startsWith('//')
82
82
  ? `https:${this.getDataValue('value')}`
@@ -3,7 +3,7 @@ const path = require('path')
3
3
  const fsPromise = require('fs/promises')
4
4
  const { VM } = require('vm2')
5
5
  const axios = require('axios')
6
- const { lodash, getAppByCtx, getConfig, Sequelize, moment } = require('q-koa')
6
+ const { lodash, getAppByCtx, getConfig, Sequelize, dayjs } = require('q-koa')
7
7
  const { LRUCache } = require('lru-cache')
8
8
  const cache = new LRUCache({
9
9
  max: 10,
@@ -90,7 +90,7 @@ exports.countAndMaxId = async (ctx, _data) => {
90
90
  attributes: ['id'],
91
91
  where: {
92
92
  created_at: {
93
- $lt: moment().add(-1, 'months'),
93
+ $lt: dayjs().add(-1, 'month'),
94
94
  },
95
95
  },
96
96
  order: [['id', 'DESC']],
@@ -822,7 +822,7 @@ exports.mockPay = async (ctx) => {
822
822
  ...(rest.transactionid
823
823
  ? {}
824
824
  : {
825
- transactionid: moment().valueOf() + '',
825
+ transactionid: dayjs().valueOf() + '',
826
826
  }),
827
827
  })
828
828
  ctx.SUCCESS('ok')
@@ -1,5 +1,5 @@
1
1
  const md5 = require('js-md5')
2
- const { getAppByCtx, getConfig, lodash, moment } = require('q-koa')
2
+ const { getAppByCtx, getConfig, lodash, dayjs } = require('q-koa')
3
3
  const { getAppConfig } = require('../../utils')
4
4
 
5
5
  exports.login = async (ctx) => {
@@ -229,11 +229,11 @@ exports.login = async (ctx) => {
229
229
 
230
230
  if (
231
231
  result.updated_at &&
232
- moment().diff(moment(result.updated_at), 'hours') > 24
232
+ dayjs().diff(dayjs(result.updated_at), 'hour') > 24
233
233
  ) {
234
234
  app.model.user.upsert({
235
235
  id: result.id,
236
- updated_at: moment(),
236
+ updated_at: dayjs(),
237
237
  })
238
238
  }
239
239
 
@@ -481,11 +481,11 @@ exports.checkLogin = async (ctx) => {
481
481
 
482
482
  if (
483
483
  result.updated_at &&
484
- moment().diff(moment(result.updated_at), 'hours') > 24
484
+ dayjs().diff(dayjs(result.updated_at), 'hour') > 24
485
485
  ) {
486
486
  app.model.user.upsert({
487
487
  id: result.id,
488
- updated_at: moment(),
488
+ updated_at: dayjs(),
489
489
  })
490
490
  }
491
491
  return ctx.SUCCESS({
@@ -2,7 +2,7 @@ const {
2
2
  lodash,
3
3
  getAppByCtx,
4
4
  getConfig,
5
- moment,
5
+ dayjs,
6
6
  ServiceError,
7
7
  getUserByCtx,
8
8
  } = require('q-koa')
@@ -551,11 +551,11 @@ exports.mp_login = async (ctx) => {
551
551
 
552
552
  if (
553
553
  result.updated_at &&
554
- moment().diff(moment(result.updated_at), 'hours') > 24
554
+ dayjs().diff(dayjs(result.updated_at), 'hour') > 24
555
555
  ) {
556
556
  app.model.user.upsert({
557
557
  id: result.id,
558
- updated_at: moment(),
558
+ updated_at: dayjs(),
559
559
  })
560
560
  }
561
561
 
@@ -1614,7 +1614,7 @@ exports.query_url_link = async (ctx, _data) => {
1614
1614
  const result = await weixinMp.queryUrlLink(url_link)
1615
1615
  const payLoad = {
1616
1616
  ...result,
1617
- is_out: result.expire_time * 1000 - moment().valueOf() < 0,
1617
+ is_out: result.expire_time * 1000 - dayjs().valueOf() < 0,
1618
1618
  }
1619
1619
 
1620
1620
  ctx.SUCCESS(payLoad)
@@ -2389,25 +2389,25 @@ exports.getUserPortrait = async (ctx) => {
2389
2389
  weixinMp.init()
2390
2390
 
2391
2391
  let obj = {}
2392
- const diff = moment().hour() > 8 ? -1 : -2
2392
+ const diff = dayjs().hour() > 8 ? -1 : -2
2393
2393
  if (type === 'day') {
2394
2394
  obj = {
2395
- begin_date: moment().add(diff, 'days').format('YYYYMMDD'),
2396
- end_date: moment().add(diff, 'days').format('YYYYMMDD'),
2395
+ begin_date: dayjs().add(diff, 'day').format('YYYYMMDD'),
2396
+ end_date: dayjs().add(diff, 'day').format('YYYYMMDD'),
2397
2397
  }
2398
2398
  } else if (type === 'week') {
2399
2399
  obj = {
2400
- begin_date: moment()
2401
- .add(-6 + diff, 'days')
2400
+ begin_date: dayjs()
2401
+ .add(-6 + diff, 'day')
2402
2402
  .format('YYYYMMDD'),
2403
- end_date: moment().add(diff, 'days').format('YYYYMMDD'),
2403
+ end_date: dayjs().add(diff, 'day').format('YYYYMMDD'),
2404
2404
  }
2405
2405
  } else if (type === 'month') {
2406
2406
  obj = {
2407
- begin_date: moment()
2408
- .add(-29 + diff, 'days')
2407
+ begin_date: dayjs()
2408
+ .add(-29 + diff, 'day')
2409
2409
  .format('YYYYMMDD'),
2410
- end_date: moment().add(diff, 'days').format('YYYYMMDD'),
2410
+ end_date: dayjs().add(diff, 'day').format('YYYYMMDD'),
2411
2411
  }
2412
2412
  }
2413
2413
  console.log('obj', obj)
@@ -2423,9 +2423,9 @@ exports.getVisitTrend = async (ctx, _data) => {
2423
2423
  const { config = 'weixin_mp', type = 'day', date } = _data || ctx.request.body
2424
2424
  const { app_id, app_secrect } = await appConfig.getObject(config)
2425
2425
 
2426
- const diff = moment().hour() > 8 ? -1 : -2
2426
+ const diff = dayjs().hour() > 8 ? -1 : -2
2427
2427
 
2428
- const begin_date = moment(date ? date : moment().add(diff, 'days')).format(
2428
+ const begin_date = dayjs(date ? date : dayjs().add(diff, 'day')).format(
2429
2429
  'YYYYMMDD'
2430
2430
  )
2431
2431
 
@@ -2433,8 +2433,8 @@ exports.getVisitTrend = async (ctx, _data) => {
2433
2433
  const target = await app.model.weixin_visit.findOne({
2434
2434
  where: {
2435
2435
  ref_date: date
2436
- ? Number(moment(date).format('YYYYMMDD'))
2437
- : Number(moment(begin_date).format('YYYYMMDD')),
2436
+ ? Number(dayjs(date).format('YYYYMMDD'))
2437
+ : Number(dayjs(begin_date).format('YYYYMMDD')),
2438
2438
  },
2439
2439
  })
2440
2440
  if (target) {
@@ -2448,7 +2448,7 @@ exports.getVisitTrend = async (ctx, _data) => {
2448
2448
  if (type === 'day') {
2449
2449
  obj = {
2450
2450
  begin_date,
2451
- end_date: moment(date ? date : moment().add(diff, 'days')).format(
2451
+ end_date: dayjs(date ? date : dayjs().add(diff, 'day')).format(
2452
2452
  'YYYYMMDD'
2453
2453
  ),
2454
2454
  }
@@ -2467,7 +2467,7 @@ exports.getVisitTrend = async (ctx, _data) => {
2467
2467
  } else {
2468
2468
  return app.controller.weixin.getVisitTrend(ctx, {
2469
2469
  type,
2470
- date: moment(date).add(-1, 'days').format('YYYYMMDD'),
2470
+ date: dayjs(date).add(-1, 'day').format('YYYYMMDD'),
2471
2471
  })
2472
2472
  }
2473
2473
 
@@ -3,7 +3,7 @@ const {
3
3
  getAppConfig,
4
4
  getConfig,
5
5
  lodash,
6
- moment,
6
+ dayjs,
7
7
  sleep,
8
8
  } = require('q-koa')
9
9
  const { Pay } = require('@sigodenjs/wechatpay')
@@ -1010,9 +1010,9 @@ const handleBillData = (result) => {
1010
1010
  }
1011
1011
  let order_date
1012
1012
  if (prefix) {
1013
- order_date = moment(array[0].substring(1)).format('YYYY-MM-DD') + ''
1013
+ order_date = dayjs(array[0].substring(1)).format('YYYY-MM-DD') + ''
1014
1014
  } else {
1015
- order_date = moment(
1015
+ order_date = dayjs(
1016
1016
  `${orderdate.slice(0, 4)}-${orderdate.slice(4, 6)}-${orderdate.slice(
1017
1017
  6,
1018
1018
  8
@@ -1150,7 +1150,7 @@ exports.union_downloadBill = async ({
1150
1150
  })
1151
1151
 
1152
1152
  const result = await allinpay.downloadBill({
1153
- date: date || moment().add(-1, 'days').format('YYYYMMDD'),
1153
+ date: date || dayjs().add(-1, 'day').format('YYYYMMDD'),
1154
1154
  })
1155
1155
 
1156
1156
  if (result && result.url) {
@@ -1292,7 +1292,7 @@ exports.union_downloadBill = async ({
1292
1292
  const orderTarget = orderList.find((o) => o.id === item.order_id)
1293
1293
  openid = orderTarget.user && orderTarget.user.mp_openid
1294
1294
  remark = `订单${orderTarget.orderid}`
1295
- order_date = moment(orderTarget.created_at).format('YYYY-MM-DD')
1295
+ order_date = dayjs(orderTarget.created_at).format('YYYY-MM-DD')
1296
1296
  application_id = orderTarget.application_id
1297
1297
  } else if (item.member_order_id) {
1298
1298
  const orderTarget = member_order_list.find(
@@ -1300,7 +1300,7 @@ exports.union_downloadBill = async ({
1300
1300
  )
1301
1301
  openid = orderTarget.user && orderTarget.user.mp_openid
1302
1302
  remark = `购买${orderTarget.application.name}会员${item.member_order_id}`
1303
- order_date = moment(orderTarget.created_at).format('YYYY-MM-DD')
1303
+ order_date = dayjs(orderTarget.created_at).format('YYYY-MM-DD')
1304
1304
  application_id = orderTarget.application_id
1305
1305
  }
1306
1306
  returnRes.push({
@@ -1,20 +1,13 @@
1
1
  const Core = require('@alicloud/pop-core')
2
- const { lodash } = require('q-koa')
3
2
  module.exports = class Singleton {
3
+ static _instanceMap = new Map()
4
4
  constructor(key) {
5
- this.key = key
6
-
7
- /**
8
- * 单例模式
9
- */
10
- if (!Singleton.instance) {
11
- Singleton.instance = this
5
+ const cacheKey = key.accessKeyId
6
+ if (Singleton._instanceMap.has(cacheKey)) {
7
+ return Singleton._instanceMap.get(cacheKey)
12
8
  }
13
- const previous = Singleton.instance.getConfig()
14
- if (!lodash.isEqual(previous, key)) {
15
- Singleton.instance = this
16
- }
17
- return Singleton.instance
9
+ this.key = key
10
+ Singleton._instanceMap.set(cacheKey, this)
18
11
  }
19
12
 
20
13
  init() {
@@ -1,7 +1,11 @@
1
1
  const crypto = require('crypto')
2
- const { lodash } = require('q-koa')
3
2
  module.exports = class Singleton {
3
+ static _instanceMap = new Map()
4
4
  constructor(config) {
5
+ const key = config.partner
6
+ if (Singleton._instanceMap.has(key)) {
7
+ return Singleton._instanceMap.get(key)
8
+ }
5
9
  this.config = {
6
10
  service: 'alipay.wap.create.direct.pay.by.user',
7
11
  partner: '',
@@ -19,17 +23,7 @@ module.exports = class Singleton {
19
23
  return_url: 'http://www.baidu.com',
20
24
  ...config,
21
25
  }
22
- /**
23
- * 单例模式
24
- */
25
- if (!Singleton.instance) {
26
- Singleton.instance = this
27
- }
28
- const previous = Singleton.instance.getConfig()
29
- if (!lodash.isEqual(previous, config)) {
30
- Singleton.instance = this
31
- }
32
- return Singleton.instance
26
+ Singleton._instanceMap.set(key, this)
33
27
  }
34
28
 
35
29
  async create() {
@@ -1,5 +1,4 @@
1
1
  const axios = require('axios')
2
- const { lodash } = require('q-koa')
3
2
 
4
3
  const queryFn = (obj) => {
5
4
  const query = Object.keys(obj)
@@ -10,20 +9,13 @@ const queryFn = (obj) => {
10
9
  return query.replace('&', '?')
11
10
  }
12
11
  module.exports = class Singleton {
12
+ static _instanceMap = new Map()
13
13
  constructor(key) {
14
- this.key = key
15
-
16
- /**
17
- * 单例模式
18
- */
19
- if (!Singleton.instance) {
20
- Singleton.instance = this
14
+ if (Singleton._instanceMap.has(key)) {
15
+ return Singleton._instanceMap.get(key)
21
16
  }
22
- const previous = Singleton.instance.getConfig()
23
- if (!lodash.isEqual(previous, key)) {
24
- Singleton.instance = this
25
- }
26
- return Singleton.instance
17
+ this.key = key
18
+ Singleton._instanceMap.set(key, this)
27
19
  }
28
20
 
29
21
  async geo({ address }) {
@@ -1,6 +1,5 @@
1
1
  const util = require('util')
2
2
  const axios = require('axios')
3
- const { lodash } = require('q-koa')
4
3
 
5
4
  const commonTokenUrl =
6
5
  'https://open.douyin.com/oauth/client_token/?client_key=%s&client_secret=%s&grant_type=client_credential'
@@ -20,28 +19,23 @@ const cache = new LRUCache({
20
19
  })
21
20
 
22
21
  module.exports = class Singleton {
22
+ static _instanceMap = new Map()
23
23
  constructor(config) {
24
- this.config = {
25
- ...config,
24
+ const key = config.client_key
25
+ if (Singleton._instanceMap.has(key)) {
26
+ return Singleton._instanceMap.get(key)
26
27
  }
27
-
28
- /**
29
- * 单例模式
30
- */
31
- if (!Singleton.instance) {
32
- Singleton.instance = this
28
+ if (!config.client_key || !config.client_secret) {
29
+ throw new Error('没有配置client_key或client_secret')
33
30
  }
34
- const previous = Singleton.instance.getConfig()
35
- if (!lodash.isEqual(previous, config)) {
36
- Singleton.instance = this
31
+ this.config = {
32
+ ...config,
37
33
  }
38
- return Singleton.instance
34
+ Singleton._instanceMap.set(key, this)
39
35
  }
40
36
 
41
37
  init() {
42
- if (!this.config.client_key || !this.config.client_secret) {
43
- throw new Error('没有配置client_key或client_secret')
44
- }
38
+ return this
45
39
  }
46
40
 
47
41
  async getAccessToken() {
@@ -1,25 +1,18 @@
1
1
  const axios = require('axios')
2
- const { lodash } = require('q-koa')
3
2
  const { push } = require('../plugins/log/service')
4
3
 
5
4
  const send_url = 'http://wuliu.market.alicloudapi.com/kdi'
6
5
  module.exports = class Singleton {
6
+ static _instanceMap = new Map()
7
7
  constructor(config) {
8
+ const key = config.app_code
9
+ if (Singleton._instanceMap.has(key)) {
10
+ return Singleton._instanceMap.get(key)
11
+ }
8
12
  this.config = {
9
13
  app_code: config.app_code,
10
14
  }
11
-
12
- /**
13
- * 单例模式
14
- */
15
- if (!Singleton.instance) {
16
- Singleton.instance = this
17
- }
18
- const previous = Singleton.instance.getConfig()
19
- if (!lodash.isEqual(previous, config)) {
20
- Singleton.instance = this
21
- }
22
- return Singleton.instance
15
+ Singleton._instanceMap.set(key, this)
23
16
  }
24
17
 
25
18
  async send({ no }) {
@@ -1,25 +1,17 @@
1
1
  const axios = require('axios')
2
2
  const util = require('util')
3
- const { lodash } = require('q-koa')
4
3
  const toLocationUrl =
5
4
  'https://apis.map.qq.com/ws/geocoder/v1/?location=%s&key=%s'
6
5
  const toLngAndLatUrl =
7
6
  'https://apis.map.qq.com/ws/geocoder/v1/?address=%s&key=%s'
8
7
  module.exports = class Singleton {
8
+ static _instanceMap = new Map()
9
9
  constructor(key) {
10
- this.key = key
11
-
12
- /**
13
- * 单例模式
14
- */
15
- if (!Singleton.instance) {
16
- Singleton.instance = this
10
+ if (Singleton._instanceMap.has(key)) {
11
+ return Singleton._instanceMap.get(key)
17
12
  }
18
- const previous = Singleton.instance.getConfig()
19
- if (!lodash.isEqual(previous, key)) {
20
- Singleton.instance = this
21
- }
22
- return Singleton.instance
13
+ this.key = key
14
+ Singleton._instanceMap.set(key, this)
23
15
  }
24
16
 
25
17
  async direction({
@@ -1,4 +1,4 @@
1
- const { lodash, getConfig } = require('q-koa')
1
+ const { getConfig } = require('q-koa')
2
2
  const yly = require('yly-nodejs-sdk')
3
3
  // const LRU = require('lru-cache')
4
4
  // const cache = new LRU({
@@ -7,22 +7,16 @@ const yly = require('yly-nodejs-sdk')
7
7
  // })
8
8
  // const cacheKey = Symbol('print')
9
9
  module.exports = class Singleton {
10
+ static _instanceMap = new Map()
10
11
  constructor(config) {
12
+ const key = config.cid
13
+ if (Singleton._instanceMap.has(key)) {
14
+ return Singleton._instanceMap.get(key)
15
+ }
11
16
  this.config = {
12
17
  ...config,
13
18
  }
14
-
15
- /**
16
- * 单例模式
17
- */
18
- if (!Singleton.instance) {
19
- Singleton.instance = this
20
- }
21
- const previous = Singleton.instance.getConfig()
22
- if (!lodash.isEqual(previous, config)) {
23
- Singleton.instance = this
24
- }
25
- return Singleton.instance
19
+ Singleton._instanceMap.set(key, this)
26
20
  }
27
21
 
28
22
  async getAccessToken() {
@@ -1,7 +1,6 @@
1
1
  const util = require('util')
2
2
  const axios = require('axios')
3
3
  const fsPromise = require('fs/promises')
4
- const { lodash } = require('q-koa')
5
4
  const getAccessTokenUrl =
6
5
  'https://developer.toutiao.com/api/apps/token?grant_type=%s&appid=%s&secret=%s'
7
6
  const createQRCodeUrl = 'https://developer.toutiao.com/api/apps/qrcode'
@@ -15,28 +14,24 @@ const cache = new LRUCache({
15
14
  const uuid = require('node-uuid')
16
15
 
17
16
  module.exports = class Singleton {
17
+ static _instanceMap = new Map()
18
18
  constructor(config) {
19
+ const key = config.appid
20
+ if (Singleton._instanceMap.has(key)) {
21
+ return Singleton._instanceMap.get(key)
22
+ }
23
+ if (!config.appid || !config.secrect) {
24
+ throw new Error('没有配置appid或secrect')
25
+ }
19
26
  this.config = {
20
27
  ...config,
21
28
  grant_type: 'client_credential',
22
29
  }
23
-
24
- /**
25
- * 单例模式
26
- */
27
- if (!Singleton.instance) {
28
- Singleton.instance = this
29
- }
30
- const previous = Singleton.instance.getConfig()
31
- if (!lodash.isEqual(previous, config)) {
32
- Singleton.instance = this
33
- }
34
- return Singleton.instance
30
+ Singleton._instanceMap.set(key, this)
35
31
  }
36
32
 
37
33
  init() {
38
- if (!this.config.appid || !this.config.secrect)
39
- throw new Error('没有配置appid或secrect')
34
+ return this
40
35
  }
41
36
 
42
37
  async getAccessToken() {
@@ -9,31 +9,27 @@ const cache = new LRUCache({
9
9
  max: 100,
10
10
  ttl: 1000 * 60 * 60,
11
11
  })
12
- const { lodash } = require('q-koa')
13
12
 
14
13
  module.exports = class Singleton {
14
+ static _instanceMap = new Map()
15
15
  constructor(config) {
16
+ const key = config.appid
17
+ if (Singleton._instanceMap.has(key)) {
18
+ return Singleton._instanceMap.get(key)
19
+ }
20
+ if (!config.appid || !config.secrect) {
21
+ throw new Error('没有配置appid或secrect')
22
+ }
16
23
  this.config = {
17
24
  ...config,
18
25
 
19
26
  noncestr: 'kuashou',
20
27
  grant_type: 'client_credential',
21
28
  }
22
- /**
23
- * 单例模式
24
- */
25
- if (!Singleton.instance) {
26
- Singleton.instance = this
27
- }
28
- const previous = Singleton.instance.getConfig()
29
- if (!lodash.isEqual(previous, config)) {
30
- Singleton.instance = this
31
- }
32
- return Singleton.instance
29
+ Singleton._instanceMap.set(key, this)
33
30
  }
34
31
  init() {
35
- if (!this.config.appid || !this.config.secrect)
36
- throw new Error('没有配置appid或secrect')
32
+ return this
37
33
  }
38
34
  async getAccessToken() {
39
35
  const { appid, secrect, grant_type } = this.config
@@ -1,5 +1,5 @@
1
1
  const cheerio = require('cheerio')
2
- const moment = require('moment')
2
+ const dayjs = require('dayjs')
3
3
 
4
4
  exports.handleHtml = async function (html) {
5
5
  const $ = cheerio.load(html, {
@@ -40,7 +40,7 @@ exports.handleHtml = async function (html) {
40
40
  // html = deal(html)
41
41
  // html = html.replace('url("', 'url(\'')
42
42
  // html = html.replace('")', '\')')
43
- const publish_time = moment(parseInt(ct + '000'))
43
+ const publish_time = dayjs(parseInt(ct + '000'))
44
44
  return {
45
45
  asyncTasks,
46
46
  image,
@@ -1,3 +1,13 @@
1
+ /**
2
+ * weixinMP.js — 按静态 Map 实例缓存优化后
3
+ *
4
+ * 改动点:
5
+ * 1. 删除 Singleton.instance + lodash.isEqual 的假单例
6
+ * 2. 新增 static _instanceMap = new Map(),key 为 config.appid
7
+ * 3. 构造函数按 appid 直接命中缓存,不再做深比较
8
+ * 4. 其余逻辑(url 常量 / cache LRU / 所有方法)保持不变
9
+ */
10
+
1
11
  const util = require('util')
2
12
  const axios = require('axios')
3
13
  const crypto = require('crypto')
@@ -105,7 +115,7 @@ const b2bFinishUrl =
105
115
 
106
116
  const fsPromise = require('fs/promises')
107
117
  const { LRUCache } = require('lru-cache')
108
- const request = require('request')
118
+ const FormData = require('form-data')
109
119
  const cache = new LRUCache({
110
120
  max: 100,
111
121
  ttl: 1000 * 60 * 60,
@@ -114,20 +124,11 @@ const uuid = require('node-uuid')
114
124
  const hmacSha256 = (data, secret) => {
115
125
  return crypto.createHmac('sha256', secret).update(data).digest('hex')
116
126
  }
117
- const uploadPromise = (options) => {
118
- return new Promise((resolve, reject) => {
119
- request.post(
120
- {
121
- ...options,
122
- },
123
- (err, response, body) => {
124
- if (err || response.statusCode !== 200) {
125
- reject(err)
126
- }
127
- resolve(JSON.parse(body))
128
- }
129
- )
127
+ const uploadPromise = async (url, formData) => {
128
+ const response = await axios.post(url, formData, {
129
+ headers: formData.getHeaders(),
130
130
  })
131
+ return response.data
131
132
  }
132
133
 
133
134
  const https = require('https')
@@ -145,28 +146,26 @@ const wxHttpsAgent = new https.Agent({
145
146
  axios.defaults.httpsAgent = wxHttpsAgent
146
147
 
147
148
  module.exports = class Singleton {
149
+ static _instanceMap = new Map()
150
+
148
151
  constructor(config) {
152
+ const key = config.appid
153
+ const cached = Singleton._instanceMap.get(key)
154
+ if (cached) {
155
+ return cached
156
+ }
157
+ if (!config.appid || !config.secrect) {
158
+ throw new Error('没有配置appid或secrect')
159
+ }
149
160
  this.config = {
150
161
  ...config,
151
162
  grant_type: 'client_credential',
152
163
  }
153
- /**
154
- * 单例模式
155
- */
156
- if (!Singleton.instance) {
157
- Singleton.instance = this
158
- }
159
- const previous = Singleton.instance.getConfig()
160
- if (!lodash.isEqual(previous, config)) {
161
- Singleton.instance = this
162
- }
163
- return Singleton.instance
164
+ Singleton._instanceMap.set(key, this)
164
165
  }
165
166
 
166
167
  init() {
167
- if (!this.config.appid || !this.config.secrect) {
168
- throw new Error('没有配置appid或secrect')
169
- }
168
+ return this
170
169
  }
171
170
 
172
171
  async getAccessToken() {
@@ -315,24 +314,24 @@ module.exports = class Singleton {
315
314
  const url = util.format(createLiveUrl, access_token)
316
315
 
317
316
  const formatOptions = {
318
- name, // 房间名字
319
- coverImg, // 通过 uploadfile 上传,填写 mediaID
320
- startTime, // 开始时间
321
- endTime, // 结束时间
322
- anchorName, // 主播昵称
323
- anchorWechat, // 主播微信号
324
- subAnchorWechat, // 主播副号微信号
325
- createrWechat, // 创建者微信号
326
- shareImg, // 通过 uploadfile 上传,填写 mediaID
327
- feedsImg, // 通过 uploadfile 上传,填写 mediaID
328
- isFeedsPublic: 0, // 是否开启官方收录,1 开启,0 关闭
329
- type: 0, // 直播类型,1 推流 0 手机直播
330
- closeLike: 0, // 是否关闭点赞 1:关闭
331
- closeGoods: 1, // 是否关闭商品货架,1:关闭
332
- closeComment: 1, // 是否开启评论,1:关闭
333
- closeReplay, // 是否关闭回放 1 关闭
334
- closeShare: 1, // 是否关闭分享 1 关闭
335
- closeKf: 1, // 是否关闭客服,1 关闭
317
+ name,
318
+ coverImg,
319
+ startTime,
320
+ endTime,
321
+ anchorName,
322
+ anchorWechat,
323
+ subAnchorWechat,
324
+ createrWechat,
325
+ shareImg,
326
+ feedsImg,
327
+ isFeedsPublic: 0,
328
+ type: 0,
329
+ closeLike: 0,
330
+ closeGoods: 1,
331
+ closeComment: 1,
332
+ closeReplay,
333
+ closeShare: 1,
334
+ closeKf: 1,
336
335
  }
337
336
  const result = await axios.post(url, formatOptions).then((res) => res.data)
338
337
  if (result.errcode) {
@@ -625,13 +624,11 @@ module.exports = class Singleton {
625
624
 
626
625
  const access_token = await this.getAccessToken()
627
626
  const url = util.format(uploadFile, access_token, 'image')
628
- const formData = {
629
- media: request(imgUrl.startsWith('//') ? `http:${imgUrl}` : imgUrl),
630
- }
631
- const uploadResult = await uploadPromise({
632
- url,
633
- formData,
634
- })
627
+ const fullUrl = imgUrl.startsWith('//') ? `http:${imgUrl}` : imgUrl
628
+ const stream = (await axios.get(fullUrl, { responseType: 'stream' })).data
629
+ const formData = new FormData()
630
+ formData.append('media', stream)
631
+ const uploadResult = await uploadPromise(url, formData)
635
632
  if (uploadResult.errcode) {
636
633
  if (uploadResult.errcode === 40001) {
637
634
  cache.reset()
@@ -1203,21 +1200,6 @@ module.exports = class Singleton {
1203
1200
  return result
1204
1201
  }
1205
1202
 
1206
- // async b2bFinish(payLoad) {
1207
- // const access_token = await this.getAccessToken()
1208
- // const url = util.format(b2bFinishUrl, access_token)
1209
-
1210
- // const result = await axios.post(url, payLoad).then((res) => res.data)
1211
- // if (result.errcode) {
1212
- // if (result.errcode === 40001) {
1213
- // cache.reset()
1214
- // return await this.b2bFinish(payLoad)
1215
- // }
1216
- // throw new Error(`${result.errcode};${result.errmsg}`)
1217
- // }
1218
- // return result
1219
- // }
1220
-
1221
1203
  async b2bFinish({ mchid, app_key, out_trade_no }) {
1222
1204
  const requestUrl = b2bFinishUrl
1223
1205
 
@@ -38,28 +38,24 @@ const cache = new LRUCache({
38
38
  })
39
39
 
40
40
  module.exports = class Singleton {
41
+ static _instanceMap = new Map()
41
42
  constructor(config) {
43
+ const key = config.appid
44
+ if (Singleton._instanceMap.has(key)) {
45
+ return Singleton._instanceMap.get(key)
46
+ }
47
+ if (!config.appid || !config.secrect) {
48
+ throw new Error('没有配置appid或secrect')
49
+ }
42
50
  this.config = {
43
51
  ...config,
44
52
  grant_type: 'client_credential',
45
53
  }
46
- /**
47
- * 单例模式
48
- */
49
- if (!Singleton.instance) {
50
- Singleton.instance = this
51
- }
52
- const previous = Singleton.instance.getConfig()
53
- if (!lodash.isEqual(previous, config)) {
54
- Singleton.instance = this
55
- }
56
- return Singleton.instance
54
+ Singleton._instanceMap.set(key, this)
57
55
  }
58
56
 
59
57
  init() {
60
- if (!this.config.appid || !this.config.secrect) {
61
- throw new Error('没有配置appid或secrect')
62
- }
58
+ return this
63
59
  }
64
60
 
65
61
  async getAccessToken() {
@@ -1,7 +1,7 @@
1
1
  const { lodash } = require('q-koa')
2
2
  const Sequelize = require('sequelize')
3
3
  const md5 = require('md5')
4
- const moment = require('moment')
4
+ const dayjs = require('dayjs')
5
5
  const _ = require('lodash')
6
6
 
7
7
  const findConfig = (type) => (item) =>
@@ -354,22 +354,22 @@ const filterFunction = (target, data) => {
354
354
  if (_.isObject(target[key])) {
355
355
  if ('$gt' in target[key]) {
356
356
  if (key.endsWith('time') || key.endsWith('_at')) {
357
- return moment(data[key]).diff(moment(target[key].$gt), 'seconds') > 0
357
+ return dayjs(data[key]).diff(dayjs(target[key].$gt), 'second') > 0
358
358
  }
359
359
  return data[key] > target[key].$gt
360
360
  } else if ('$gte' in target[key]) {
361
361
  if (key.endsWith('time') || key.endsWith('_at')) {
362
- return moment(data[key]).diff(moment(target[key].$gt), 'seconds') >= 0
362
+ return dayjs(data[key]).diff(dayjs(target[key].$gt), 'second') >= 0
363
363
  }
364
364
  return data[key] >= target[key].$gte
365
365
  } else if ('$lt' in target[key]) {
366
366
  if (key.endsWith('time') || key.endsWith('_at')) {
367
- return moment(target[key].$gt).diff(moment(data[key]), 'seconds') < 0
367
+ return dayjs(target[key].$lt).diff(dayjs(data[key]), 'second') < 0
368
368
  }
369
369
  return data[key] < target[key].$lt
370
370
  } else if ('$lte' in target[key]) {
371
371
  if (key.endsWith('time') || key.endsWith('_at')) {
372
- return moment(target[key].$gt).diff(moment(data[key]), 'seconds') <= 0
372
+ return dayjs(target[key].$lte).diff(dayjs(data[key]), 'second') <= 0
373
373
  }
374
374
  return data[key] <= target[key].$lte
375
375
  } else if ('$notIn' in target[key]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q-koa",
3
- "version": "13.6.4",
3
+ "version": "13.7.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -46,7 +46,6 @@
46
46
  "lodash": "^4.17.15",
47
47
  "lru-cache": "^11.5.2",
48
48
  "mockjs": "^1.0.1-beta3",
49
- "moment": "^2.24.0",
50
49
  "mysql2": "^1.7.0",
51
50
  "nodemailer": "^6.4.2",
52
51
  "ora": "^4.0.3",
@@ -63,7 +62,7 @@
63
62
  "xlsx": "^0.18.5",
64
63
  "pm2": "^7.0.1",
65
64
  "dayjs": "^1.11.13",
66
- "request": "^2.88.2"
65
+ "form-data": "^4.0.0"
67
66
  },
68
67
  "devDependencies": {
69
68
  "eslint": "^4.19.1",