q-koa 13.4.2 → 13.4.5
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 +20 -15
- package/core/config.js +2 -0
- package/core/file/plugins/administrator/config.js +1 -1
- package/core/file/plugins/app/controller.js +7 -1
- package/core/file/plugins/common/controller.js +77 -5
- package/core/file/plugins/douyin/controller.js +7 -1
- package/core/file/plugins/log/controller.js +2 -1
- package/core/file/plugins/model/model.js +1 -1
- package/core/file/plugins/model_attributes/config.js +8 -1
- package/core/file/plugins/permission/config.js +6 -2
- package/core/file/plugins/setting/controller.js +44 -0
- package/core/file/plugins/setting/model.js +7 -1
- package/core/file/plugins/system/controller.js +40 -6
- package/core/file/plugins/system/service.js +1 -0
- package/core/file/plugins/toutiao/controller.js +6 -1
- package/core/file/plugins/user/controller.js +29 -5
- package/core/file/plugins/weixin/controller.js +52 -9
- package/core/file/plugins/weixin/service.js +65 -52
- package/core/file/services/weixinMP.js +58 -0
- package/core/file/services/weixinOpen.js +11 -0
- package/package.json +1 -1
package/core/app.js
CHANGED
|
@@ -222,6 +222,7 @@ class APP {
|
|
|
222
222
|
this.app[appName].sign = async (user) => {
|
|
223
223
|
const result = await jwt.sign(user, secret, {
|
|
224
224
|
expiresIn,
|
|
225
|
+
algorithm: 'HS256',
|
|
225
226
|
})
|
|
226
227
|
return result
|
|
227
228
|
}
|
|
@@ -248,7 +249,9 @@ class APP {
|
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
try {
|
|
251
|
-
const { user } = await verify(token, secret
|
|
252
|
+
const { user } = await verify(token, secret, {
|
|
253
|
+
algorithms: ['HS256'],
|
|
254
|
+
})
|
|
252
255
|
if (user) {
|
|
253
256
|
if (this.config.log.request) {
|
|
254
257
|
console.log('user id ---> ', appName, '--->', user.id, user.name)
|
|
@@ -893,15 +896,11 @@ class APP {
|
|
|
893
896
|
const modelService = cloneTarget[b]
|
|
894
897
|
const newB = Object.keys(modelService).reduce((_a, _b) => {
|
|
895
898
|
const bindFn = modelService[_b].bind(this.app[appName])
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
[_b]: bindFn,
|
|
899
|
-
}
|
|
899
|
+
_a[_b] = bindFn
|
|
900
|
+
return _a
|
|
900
901
|
}, {})
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
[b]: newB,
|
|
904
|
-
}
|
|
902
|
+
a[b] = newB
|
|
903
|
+
return a
|
|
905
904
|
}, {})
|
|
906
905
|
}
|
|
907
906
|
|
|
@@ -914,10 +913,8 @@ class APP {
|
|
|
914
913
|
const modelList = Object.keys(this.app[appName].model)
|
|
915
914
|
|
|
916
915
|
const include = modelList.reduce((a, b) => {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
[b]: [],
|
|
920
|
-
}
|
|
916
|
+
a[b] = []
|
|
917
|
+
return a
|
|
921
918
|
}, {})
|
|
922
919
|
this.app[appName] = _.defaultsDeep(
|
|
923
920
|
{
|
|
@@ -1308,10 +1305,18 @@ class APP {
|
|
|
1308
1305
|
typeof where.id === 'string' &&
|
|
1309
1306
|
where.id.includes('/')
|
|
1310
1307
|
) {
|
|
1308
|
+
const arr = where.id.split('?')
|
|
1309
|
+
|
|
1310
|
+
let obj = {}
|
|
1311
|
+
if (arr[1] && arr[1].includes('id=')) {
|
|
1312
|
+
obj = {
|
|
1313
|
+
id: JSON.parse(arr[1].split('=')[1]),
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1311
1316
|
const _result = await _.get(
|
|
1312
1317
|
app[appName].controller,
|
|
1313
|
-
|
|
1314
|
-
)(ctx)
|
|
1318
|
+
arr[0].replace('/', '.')
|
|
1319
|
+
)(ctx, obj)
|
|
1315
1320
|
where.id = _result
|
|
1316
1321
|
}
|
|
1317
1322
|
|
package/core/config.js
CHANGED
|
@@ -7,6 +7,7 @@ module.exports = {
|
|
|
7
7
|
dir: 'public',
|
|
8
8
|
},
|
|
9
9
|
is_check_admin: false,
|
|
10
|
+
is_token_name: true,
|
|
10
11
|
log: {
|
|
11
12
|
request: true,
|
|
12
13
|
},
|
|
@@ -67,6 +68,7 @@ module.exports = {
|
|
|
67
68
|
'log/create',
|
|
68
69
|
'log/upsert',
|
|
69
70
|
'auto/minute',
|
|
71
|
+
'auto/second',
|
|
70
72
|
].every((item) => {
|
|
71
73
|
return !ctx.request.url.includes(item)
|
|
72
74
|
})
|
|
@@ -24,9 +24,15 @@ exports.login = async (ctx) => {
|
|
|
24
24
|
result = hasUser
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
const is_token_name = app.appConfig.is_token_name
|
|
28
|
+
|
|
27
29
|
const tokenResult = {
|
|
28
30
|
id: result.id,
|
|
29
|
-
|
|
31
|
+
...(is_token_name
|
|
32
|
+
? {
|
|
33
|
+
name: result.name,
|
|
34
|
+
}
|
|
35
|
+
: {}),
|
|
30
36
|
mp_user: result.mp_user
|
|
31
37
|
? {
|
|
32
38
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -431,20 +431,28 @@ exports.syncModel = async (ctx) => {
|
|
|
431
431
|
ctx.SUCCESS('ok')
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
exports.verify = async (ctx) => {
|
|
434
|
+
exports.verify = async (ctx, _data) => {
|
|
435
435
|
const { app, appName } = getAppByCtx(ctx)
|
|
436
|
-
const { code } = ctx.request.body
|
|
436
|
+
const { code } = _data || ctx.request.body
|
|
437
|
+
if (!code) {
|
|
438
|
+
ctx.SUCCESS(null)
|
|
439
|
+
return null
|
|
440
|
+
}
|
|
437
441
|
const verify = util.promisify(jwt.verify)
|
|
438
442
|
const result = await verify(code, 'token')
|
|
439
443
|
ctx.SUCCESS(result)
|
|
444
|
+
return result
|
|
440
445
|
}
|
|
441
446
|
|
|
442
|
-
const expressFn = async ({ app, express_number: _express_number }) => {
|
|
447
|
+
const expressFn = async ({ app, express_number: _express_number, mobile }) => {
|
|
443
448
|
const appConfig = getConfig(app)
|
|
444
|
-
const { app_code, express_mobile } =
|
|
449
|
+
const { app_code, express_mobile: default_express_mobile } =
|
|
450
|
+
await appConfig.getObject('express')
|
|
445
451
|
|
|
446
452
|
const express_number = _express_number.replace(/\t/, '').trim()
|
|
447
453
|
|
|
454
|
+
const express_mobile = mobile || default_express_mobile
|
|
455
|
+
|
|
448
456
|
const lastFour = express_mobile
|
|
449
457
|
.split('')
|
|
450
458
|
.slice(express_mobile.length - 4, express_mobile.length)
|
|
@@ -501,7 +509,7 @@ const expressFn = async ({ app, express_number: _express_number }) => {
|
|
|
501
509
|
exports.express = async (ctx) => {
|
|
502
510
|
const { app } = getAppByCtx(ctx)
|
|
503
511
|
|
|
504
|
-
const { express_number } = ctx.request.body
|
|
512
|
+
const { express_number, mobile } = ctx.request.body
|
|
505
513
|
|
|
506
514
|
if (Array.isArray(express_number)) {
|
|
507
515
|
const result = await Promise.all(
|
|
@@ -518,6 +526,7 @@ exports.express = async (ctx) => {
|
|
|
518
526
|
const result = await expressFn({
|
|
519
527
|
app,
|
|
520
528
|
express_number,
|
|
529
|
+
mobile,
|
|
521
530
|
})
|
|
522
531
|
|
|
523
532
|
return ctx.SUCCESS(result)
|
|
@@ -674,3 +683,66 @@ exports.gpt = async (ctx) => {
|
|
|
674
683
|
})
|
|
675
684
|
await sleep(1000000)
|
|
676
685
|
}
|
|
686
|
+
|
|
687
|
+
exports.copyDB = async (ctx) => {
|
|
688
|
+
const { app, appName: currentAppName } = getAppByCtx(ctx)
|
|
689
|
+
const {
|
|
690
|
+
host = '',
|
|
691
|
+
ori_appname = '',
|
|
692
|
+
break_list = [],
|
|
693
|
+
limit = 3000,
|
|
694
|
+
} = ctx.request.body
|
|
695
|
+
if (!host) {
|
|
696
|
+
throw new Error(`?host`)
|
|
697
|
+
}
|
|
698
|
+
const list = Object.keys(app.model)
|
|
699
|
+
const appName = ori_appname || currentAppName
|
|
700
|
+
|
|
701
|
+
for (const model of list) {
|
|
702
|
+
if (break_list.includes(model)) {
|
|
703
|
+
console.log(`跳过`)
|
|
704
|
+
continue
|
|
705
|
+
}
|
|
706
|
+
const count = await app.model[model].count()
|
|
707
|
+
if (count > 0) {
|
|
708
|
+
console.log(`有数据,跳过`)
|
|
709
|
+
continue
|
|
710
|
+
}
|
|
711
|
+
await app.model[model].sync({
|
|
712
|
+
force: true,
|
|
713
|
+
})
|
|
714
|
+
const url = `${host}/${appName}/${model}/findAll`
|
|
715
|
+
for (let i = 0; i < 10000; i++) {
|
|
716
|
+
console.log(`page-${i}`)
|
|
717
|
+
const { code, data } = await axios
|
|
718
|
+
.post(url, {
|
|
719
|
+
offset: i * limit,
|
|
720
|
+
limit,
|
|
721
|
+
where: {
|
|
722
|
+
id: {
|
|
723
|
+
$gt: 0,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
...(model === 'setting'
|
|
727
|
+
? {
|
|
728
|
+
raw: true,
|
|
729
|
+
}
|
|
730
|
+
: {}),
|
|
731
|
+
autoInclude: false,
|
|
732
|
+
})
|
|
733
|
+
.then((res) => res.data)
|
|
734
|
+
|
|
735
|
+
if (code !== 200) {
|
|
736
|
+
break
|
|
737
|
+
}
|
|
738
|
+
await app.model[model].bulkCreate(data)
|
|
739
|
+
if (data.length < limit) {
|
|
740
|
+
break
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
console.log(`${model}结束`)
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
ctx.SUCCESS('ok')
|
|
748
|
+
}
|
|
@@ -147,9 +147,15 @@ exports.login_callback = async (ctx) => {
|
|
|
147
147
|
],
|
|
148
148
|
})
|
|
149
149
|
|
|
150
|
+
const is_token_name = app.appConfig.is_token_name
|
|
151
|
+
|
|
150
152
|
const tokenResult = {
|
|
151
153
|
id: result.id,
|
|
152
|
-
|
|
154
|
+
...(is_token_name
|
|
155
|
+
? {
|
|
156
|
+
name: result.name,
|
|
157
|
+
}
|
|
158
|
+
: {}),
|
|
153
159
|
h5_user: result.h5_user
|
|
154
160
|
? {
|
|
155
161
|
openid: result.h5_user && result.h5_user.openid,
|
|
@@ -33,11 +33,12 @@ exports.clearWeixin = async (ctx) => {
|
|
|
33
33
|
exports.push = async (ctx) => {
|
|
34
34
|
const { app, appName } = getAppByCtx(ctx)
|
|
35
35
|
|
|
36
|
-
const { message = '测试通知' } = ctx.request.body
|
|
36
|
+
const { message = '测试通知', url } = ctx.request.body
|
|
37
37
|
|
|
38
38
|
await app.service.log.push({
|
|
39
39
|
app,
|
|
40
40
|
message,
|
|
41
|
+
url,
|
|
41
42
|
})
|
|
42
43
|
|
|
43
44
|
ctx.SUCCESS('ok')
|
|
@@ -4,7 +4,11 @@ module.exports = {
|
|
|
4
4
|
multiple: false,
|
|
5
5
|
availableSort: false,
|
|
6
6
|
order: [],
|
|
7
|
-
select: [
|
|
7
|
+
select: [
|
|
8
|
+
{
|
|
9
|
+
key: 'controller',
|
|
10
|
+
},
|
|
11
|
+
],
|
|
8
12
|
excludes: [],
|
|
9
13
|
limit: 20,
|
|
10
14
|
defaultOrder: [],
|
|
@@ -12,4 +16,4 @@ module.exports = {
|
|
|
12
16
|
sortOrder: 1,
|
|
13
17
|
reference: [],
|
|
14
18
|
excludeAuth: [],
|
|
15
|
-
}
|
|
19
|
+
}
|
|
@@ -157,3 +157,47 @@ exports.html = async (ctx) => {
|
|
|
157
157
|
</body>
|
|
158
158
|
</html>`
|
|
159
159
|
}
|
|
160
|
+
|
|
161
|
+
exports.getList = async (ctx, _data) => {
|
|
162
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
163
|
+
|
|
164
|
+
const { type = 'is_custom' } = _data || ctx.request.body
|
|
165
|
+
|
|
166
|
+
const settingList = await app.model.setting.findAll({
|
|
167
|
+
where: {
|
|
168
|
+
$or: [
|
|
169
|
+
{
|
|
170
|
+
is_front: true,
|
|
171
|
+
},
|
|
172
|
+
type
|
|
173
|
+
? {
|
|
174
|
+
extra: {
|
|
175
|
+
[type]: true,
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
: null,
|
|
179
|
+
].filter(Boolean),
|
|
180
|
+
},
|
|
181
|
+
attributes: {
|
|
182
|
+
exclude: [
|
|
183
|
+
'name',
|
|
184
|
+
'created_at',
|
|
185
|
+
'updated_at',
|
|
186
|
+
'createdid',
|
|
187
|
+
'is_cache',
|
|
188
|
+
'is_front',
|
|
189
|
+
'is_control',
|
|
190
|
+
'extra',
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
const payLoad = settingList.map((item) => {
|
|
196
|
+
return lodash.omit(item.toJSON(), [
|
|
197
|
+
'type',
|
|
198
|
+
item.parent_id === 0 ? '' : 'id',
|
|
199
|
+
])
|
|
200
|
+
})
|
|
201
|
+
ctx.SUCCESS(payLoad)
|
|
202
|
+
return payLoad
|
|
203
|
+
}
|
|
@@ -141,7 +141,13 @@ exports.extra = {
|
|
|
141
141
|
sortOrder: 9,
|
|
142
142
|
set: function (value) {
|
|
143
143
|
try {
|
|
144
|
-
const dataValue =
|
|
144
|
+
const dataValue =
|
|
145
|
+
value === null
|
|
146
|
+
? {}
|
|
147
|
+
: typeof value === 'object'
|
|
148
|
+
? value
|
|
149
|
+
: JSON.parse(value)
|
|
150
|
+
|
|
145
151
|
this.setDataValue('extra', dataValue)
|
|
146
152
|
} catch {
|
|
147
153
|
throw new Error('extra值不合法')
|
|
@@ -78,13 +78,13 @@ exports.countAndMaxId = async (ctx, _data) => {
|
|
|
78
78
|
ctx.SUCCESS(null)
|
|
79
79
|
return null
|
|
80
80
|
}
|
|
81
|
-
const count = await app.model[model].count()
|
|
82
|
-
const current = await app.model[model].findOne({
|
|
83
|
-
attributes: ['id', 'created_at'],
|
|
84
|
-
order: [['id', 'DESC']],
|
|
85
|
-
})
|
|
86
81
|
|
|
87
|
-
const
|
|
82
|
+
const result = await app.sequelize.query(
|
|
83
|
+
`select * from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '${app.sequelize.config.database}' and TABLE_NAME = '${model}'`
|
|
84
|
+
)
|
|
85
|
+
const count = result[0][0].TABLE_ROWS
|
|
86
|
+
|
|
87
|
+
const current_max_id = result[0][0].AUTO_INCREMENT
|
|
88
88
|
|
|
89
89
|
const lastMonth = await app.model[model].findOne({
|
|
90
90
|
attributes: ['id'],
|
|
@@ -933,6 +933,40 @@ exports.checkIndex = async (ctx) => {
|
|
|
933
933
|
}
|
|
934
934
|
}
|
|
935
935
|
|
|
936
|
+
exports.checkAttribute = async (ctx) => {
|
|
937
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
938
|
+
const { model } = ctx.request.body
|
|
939
|
+
|
|
940
|
+
if (!model) return ctx.ERROR('model不能为空')
|
|
941
|
+
|
|
942
|
+
const result = await app.sequelize.getQueryInterface().describeTable(model)
|
|
943
|
+
|
|
944
|
+
const attributeList = Object.keys(result).filter(
|
|
945
|
+
(item) => !['id', 'created_at', 'createdid', 'updated_at'].includes(item)
|
|
946
|
+
)
|
|
947
|
+
|
|
948
|
+
const currentAttributeList = Object.keys(app.attributes[model]).filter(
|
|
949
|
+
(item) => {
|
|
950
|
+
return app.attributes[model][item].type !== Sequelize.VIRTUAL
|
|
951
|
+
}
|
|
952
|
+
)
|
|
953
|
+
|
|
954
|
+
let flag = true
|
|
955
|
+
if (attributeList.length !== currentAttributeList.length) {
|
|
956
|
+
flag = false
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
const current = attributeList.filter(
|
|
960
|
+
(item) => !currentAttributeList.includes(item)
|
|
961
|
+
)
|
|
962
|
+
|
|
963
|
+
ctx.SUCCESS({
|
|
964
|
+
isSame: flag,
|
|
965
|
+
current,
|
|
966
|
+
remote: [],
|
|
967
|
+
})
|
|
968
|
+
}
|
|
969
|
+
|
|
936
970
|
exports.dropIndex = async (ctx) => {
|
|
937
971
|
const { app, appName } = getAppByCtx(ctx)
|
|
938
972
|
const { model, key } = ctx.request.body
|
|
@@ -80,6 +80,7 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
|
80
80
|
const omit = data && data.omit ? data.omit : []
|
|
81
81
|
const pick = data && data.pick ? data.pick : []
|
|
82
82
|
const cacheData = app.cache.get(`${model}`) || []
|
|
83
|
+
|
|
83
84
|
const cacheList = cacheData
|
|
84
85
|
.map((i) => (i.toJSON ? i.toJSON() : i))
|
|
85
86
|
.filter((c) => {
|
|
@@ -160,10 +160,15 @@ exports.login = async (ctx) => {
|
|
|
160
160
|
...app.include.user,
|
|
161
161
|
],
|
|
162
162
|
})
|
|
163
|
+
const is_token_name = app.appConfig.is_token_name
|
|
163
164
|
|
|
164
165
|
const tokenResult = {
|
|
165
166
|
id: result.id,
|
|
166
|
-
|
|
167
|
+
...(is_token_name
|
|
168
|
+
? {
|
|
169
|
+
name: result.name,
|
|
170
|
+
}
|
|
171
|
+
: {}),
|
|
167
172
|
mp_user: result.mp_user
|
|
168
173
|
? {
|
|
169
174
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -8,6 +8,8 @@ exports.login = async (ctx) => {
|
|
|
8
8
|
|
|
9
9
|
const config = _config || ctx.request.header.config || 'weixin_mp'
|
|
10
10
|
|
|
11
|
+
const is_token_name = app.appConfig.is_token_name
|
|
12
|
+
|
|
11
13
|
const where =
|
|
12
14
|
process.env.NODE_ENV !== 'production'
|
|
13
15
|
? {
|
|
@@ -41,7 +43,11 @@ exports.login = async (ctx) => {
|
|
|
41
43
|
if (_config === 'none') {
|
|
42
44
|
const tokenResult = {
|
|
43
45
|
id: result.id,
|
|
44
|
-
|
|
46
|
+
...(is_token_name
|
|
47
|
+
? {
|
|
48
|
+
name: result.name,
|
|
49
|
+
}
|
|
50
|
+
: {}),
|
|
45
51
|
}
|
|
46
52
|
const token = await app.sign({
|
|
47
53
|
user: tokenResult,
|
|
@@ -192,7 +198,11 @@ exports.login = async (ctx) => {
|
|
|
192
198
|
|
|
193
199
|
const tokenResult = {
|
|
194
200
|
id: result.id,
|
|
195
|
-
|
|
201
|
+
...(is_token_name
|
|
202
|
+
? {
|
|
203
|
+
name: result.name,
|
|
204
|
+
}
|
|
205
|
+
: {}),
|
|
196
206
|
mp_user: result.mp_user
|
|
197
207
|
? {
|
|
198
208
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -315,11 +325,12 @@ exports.checkLogin = async (ctx) => {
|
|
|
315
325
|
const config = _config || 'weixin_mp'
|
|
316
326
|
const appConfig = getConfig(app)
|
|
317
327
|
if (ctx.request[`${appName}-user`] && ctx.request[`${appName}-user`].id) {
|
|
328
|
+
const { app_id: appid } = await appConfig.getObject(config)
|
|
318
329
|
const h5_user_include = config.includes('h5')
|
|
319
330
|
? {
|
|
320
331
|
model: app.model.h5_user,
|
|
321
332
|
where: {
|
|
322
|
-
appid
|
|
333
|
+
appid,
|
|
323
334
|
},
|
|
324
335
|
attributes: {
|
|
325
336
|
exclude: ['created_at', 'updated_at', 'createdid'],
|
|
@@ -331,14 +342,18 @@ exports.checkLogin = async (ctx) => {
|
|
|
331
342
|
const mp_user_include = config.includes('mp')
|
|
332
343
|
? {
|
|
333
344
|
model: app.model.mp_user,
|
|
345
|
+
attributes: ['openid', 'unionid'],
|
|
334
346
|
where: {
|
|
335
|
-
appid
|
|
347
|
+
appid,
|
|
336
348
|
},
|
|
337
349
|
}
|
|
338
350
|
: {
|
|
339
351
|
model: app.model.mp_user,
|
|
352
|
+
attributes: ['openid', 'unionid'],
|
|
340
353
|
}
|
|
354
|
+
|
|
341
355
|
let result
|
|
356
|
+
|
|
342
357
|
const includeDefault = [
|
|
343
358
|
{
|
|
344
359
|
model: app.model.github_user,
|
|
@@ -353,6 +368,7 @@ exports.checkLogin = async (ctx) => {
|
|
|
353
368
|
|
|
354
369
|
if (app.appConfig.loginData) {
|
|
355
370
|
const application = await getAppConfig({ app, config })
|
|
371
|
+
|
|
356
372
|
const loginData = lodash.mergeWith(
|
|
357
373
|
lodash.cloneDeep(app.appConfig.loginData),
|
|
358
374
|
lodash.get(application, 'loginData', {}),
|
|
@@ -379,6 +395,7 @@ exports.checkLogin = async (ctx) => {
|
|
|
379
395
|
])
|
|
380
396
|
),
|
|
381
397
|
}
|
|
398
|
+
|
|
382
399
|
result = await app.model.user.findOne({
|
|
383
400
|
where: {
|
|
384
401
|
id: ctx.request[`${appName}-user`].id,
|
|
@@ -428,9 +445,15 @@ exports.checkLogin = async (ctx) => {
|
|
|
428
445
|
}
|
|
429
446
|
}
|
|
430
447
|
|
|
448
|
+
const is_token_name = app.appConfig.is_token_name
|
|
449
|
+
|
|
431
450
|
const tokenResult = {
|
|
432
451
|
id: result.id,
|
|
433
|
-
|
|
452
|
+
...(is_token_name
|
|
453
|
+
? {
|
|
454
|
+
name: result.name,
|
|
455
|
+
}
|
|
456
|
+
: {}),
|
|
434
457
|
mp_user: result.mp_user
|
|
435
458
|
? {
|
|
436
459
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -451,6 +474,7 @@ exports.checkLogin = async (ctx) => {
|
|
|
451
474
|
}
|
|
452
475
|
: {}),
|
|
453
476
|
}
|
|
477
|
+
|
|
454
478
|
const token = await app.sign({
|
|
455
479
|
user: tokenResult,
|
|
456
480
|
})
|
|
@@ -94,8 +94,17 @@ exports.mp_getPhone = async (ctx) => {
|
|
|
94
94
|
(!exist.mp_user.appid || exist.mp_user.appid === app_id)
|
|
95
95
|
|
|
96
96
|
if (mobileExist) {
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
const formatMobile = (mobile) => {
|
|
98
|
+
if (!mobile) return ''
|
|
99
|
+
return mobile.slice(0, 3) + '*****' + mobile.slice(8, mobile.length)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const user_id = getUserByCtx(ctx)
|
|
103
|
+
app.service.log.push({
|
|
104
|
+
app,
|
|
105
|
+
message: `系统已存在该手机号${phoneNumber};${user_id}`,
|
|
106
|
+
})
|
|
107
|
+
return ctx.ERROR(`系统已存在该手机号`)
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
const userResult = await app.model.mp_user.findOne({
|
|
@@ -130,9 +139,15 @@ exports.mp_getPhone = async (ctx) => {
|
|
|
130
139
|
].filter((item) => item.model),
|
|
131
140
|
})
|
|
132
141
|
|
|
142
|
+
const is_token_name = app.appConfig.is_token_name
|
|
143
|
+
|
|
133
144
|
const tokenResult = {
|
|
134
145
|
id: result.id,
|
|
135
|
-
|
|
146
|
+
...(is_token_name
|
|
147
|
+
? {
|
|
148
|
+
name: result.name,
|
|
149
|
+
}
|
|
150
|
+
: {}),
|
|
136
151
|
mp_user: result.mp_user
|
|
137
152
|
? {
|
|
138
153
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -251,9 +266,15 @@ exports.mp_getPhoneNew = async (ctx) => {
|
|
|
251
266
|
].filter((item) => item.model),
|
|
252
267
|
})
|
|
253
268
|
|
|
269
|
+
const is_token_name = app.appConfig.is_token_name
|
|
270
|
+
|
|
254
271
|
const tokenResult = {
|
|
255
272
|
id: result.id,
|
|
256
|
-
|
|
273
|
+
...(is_token_name
|
|
274
|
+
? {
|
|
275
|
+
name: result.name,
|
|
276
|
+
}
|
|
277
|
+
: {}),
|
|
257
278
|
mp_user: result.mp_user
|
|
258
279
|
? {
|
|
259
280
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -492,9 +513,15 @@ exports.mp_login = async (ctx) => {
|
|
|
492
513
|
|
|
493
514
|
if (!(result && result.id)) throw new Error('登录失败')
|
|
494
515
|
|
|
516
|
+
const is_token_name = app.appConfig.is_token_name
|
|
517
|
+
|
|
495
518
|
const tokenResult = {
|
|
496
519
|
id: result.id,
|
|
497
|
-
|
|
520
|
+
...(is_token_name
|
|
521
|
+
? {
|
|
522
|
+
name: result.name,
|
|
523
|
+
}
|
|
524
|
+
: {}),
|
|
498
525
|
mp_user: result.mp_user
|
|
499
526
|
? {
|
|
500
527
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -671,9 +698,15 @@ exports.h5_login_callback = async (ctx) => {
|
|
|
671
698
|
].filter((item) => item.model),
|
|
672
699
|
})
|
|
673
700
|
|
|
701
|
+
const is_token_name = app.appConfig.is_token_name
|
|
702
|
+
|
|
674
703
|
const tokenResult = {
|
|
675
704
|
id: result.id,
|
|
676
|
-
|
|
705
|
+
...(is_token_name
|
|
706
|
+
? {
|
|
707
|
+
name: result.name,
|
|
708
|
+
}
|
|
709
|
+
: {}),
|
|
677
710
|
mp_user: result.mp_user
|
|
678
711
|
? {
|
|
679
712
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -805,9 +838,15 @@ exports.h5_login_info_callback = async (ctx) => {
|
|
|
805
838
|
].filter((item) => item.model),
|
|
806
839
|
})
|
|
807
840
|
|
|
841
|
+
const is_token_name = app.appConfig.is_token_name
|
|
842
|
+
|
|
808
843
|
const tokenResult = {
|
|
809
844
|
id: result.id,
|
|
810
|
-
|
|
845
|
+
...(is_token_name
|
|
846
|
+
? {
|
|
847
|
+
name: result.name,
|
|
848
|
+
}
|
|
849
|
+
: {}),
|
|
811
850
|
mp_user: result.mp_user
|
|
812
851
|
? {
|
|
813
852
|
openid: result.mp_user && result.mp_user.openid,
|
|
@@ -1013,6 +1052,7 @@ exports.mp_pay = async (ctx) => {
|
|
|
1013
1052
|
config = 'weixin_mp',
|
|
1014
1053
|
pay_config = 'weixin_pay',
|
|
1015
1054
|
profit_sharing = 'N',
|
|
1055
|
+
mch_id = '',
|
|
1016
1056
|
} = ctx.request.body
|
|
1017
1057
|
if (price === 0) throw new Error('价格不能为0')
|
|
1018
1058
|
|
|
@@ -1036,7 +1076,7 @@ exports.mp_pay = async (ctx) => {
|
|
|
1036
1076
|
key,
|
|
1037
1077
|
pay_key: _pay_key,
|
|
1038
1078
|
partner_key,
|
|
1039
|
-
} = await appConfig.getObject(pay_config)
|
|
1079
|
+
} = await appConfig.getObject(mch_id || pay_config)
|
|
1040
1080
|
|
|
1041
1081
|
const pay_key = _pay_key || key || appName
|
|
1042
1082
|
const { is_dev, site_host } = await appConfig.getObject('base')
|
|
@@ -1048,7 +1088,7 @@ exports.mp_pay = async (ctx) => {
|
|
|
1048
1088
|
|
|
1049
1089
|
const wxpay = WXPay({
|
|
1050
1090
|
appid: app_id,
|
|
1051
|
-
mch_id: mchId,
|
|
1091
|
+
mch_id: mchId || mch_id,
|
|
1052
1092
|
partner_key, // 微信商户平台API密钥
|
|
1053
1093
|
})
|
|
1054
1094
|
|
|
@@ -1645,6 +1685,7 @@ exports.checkPayOnly = async (ctx, _data) => {
|
|
|
1645
1685
|
})
|
|
1646
1686
|
|
|
1647
1687
|
ctx.SUCCESS({ prefix, out_trade_no, ...payResult })
|
|
1688
|
+
return { prefix, out_trade_no, ...payResult }
|
|
1648
1689
|
}
|
|
1649
1690
|
|
|
1650
1691
|
exports.checkRefund = async (ctx, _data) => {
|
|
@@ -2044,6 +2085,7 @@ exports.getCommentInfo = async (ctx, _data) => {
|
|
|
2044
2085
|
const {
|
|
2045
2086
|
content: {
|
|
2046
2087
|
orderInfo: { busiOrderId },
|
|
2088
|
+
content,
|
|
2047
2089
|
},
|
|
2048
2090
|
} = info
|
|
2049
2091
|
|
|
@@ -2060,6 +2102,7 @@ exports.getCommentInfo = async (ctx, _data) => {
|
|
|
2060
2102
|
const result = {
|
|
2061
2103
|
prefix,
|
|
2062
2104
|
order_id,
|
|
2105
|
+
content,
|
|
2063
2106
|
}
|
|
2064
2107
|
ctx.SUCCESS(result)
|
|
2065
2108
|
return result
|
|
@@ -687,7 +687,7 @@ exports.pc_pay = async ({
|
|
|
687
687
|
pay_config = 'weixin_pay',
|
|
688
688
|
out_trade_no: _out_trade_no,
|
|
689
689
|
is_admin = false,
|
|
690
|
-
type = '
|
|
690
|
+
type = 'PC-WEIXIN',
|
|
691
691
|
prefix = '',
|
|
692
692
|
}) => {
|
|
693
693
|
if (!ctx) throw new Error('?ctx')
|
|
@@ -866,6 +866,60 @@ exports.removereceiver = async ({
|
|
|
866
866
|
return res
|
|
867
867
|
}
|
|
868
868
|
|
|
869
|
+
const handleBillData = (result) => {
|
|
870
|
+
const arr = result.split('\r\n')
|
|
871
|
+
const list = arr.slice(1, arr.length - 3)
|
|
872
|
+
return {
|
|
873
|
+
header: arr[0],
|
|
874
|
+
list,
|
|
875
|
+
result: list.map((item) => {
|
|
876
|
+
const array = item.split(',')
|
|
877
|
+
const orderdate = array[20].substring(1).slice(2, 10)
|
|
878
|
+
const orderPrefix = array[6].substring(1).split('_')[1]
|
|
879
|
+
let order_id = 0
|
|
880
|
+
let prefix = ''
|
|
881
|
+
if (orderPrefix.includes('-')) {
|
|
882
|
+
order_id = Number(orderPrefix.split('-')[1])
|
|
883
|
+
prefix = orderPrefix.split('-')[0]
|
|
884
|
+
} else {
|
|
885
|
+
order_id = Number(orderPrefix)
|
|
886
|
+
}
|
|
887
|
+
let order_date
|
|
888
|
+
if (prefix) {
|
|
889
|
+
order_date = moment(array[0].substring(1)).format('YYYY-MM-DD') + ''
|
|
890
|
+
} else {
|
|
891
|
+
order_date = moment(
|
|
892
|
+
`${orderdate.slice(0, 4)}-${orderdate.slice(4, 6)}-${orderdate.slice(
|
|
893
|
+
6,
|
|
894
|
+
8
|
|
895
|
+
)}`
|
|
896
|
+
).format('YYYY-MM-DD')
|
|
897
|
+
}
|
|
898
|
+
return {
|
|
899
|
+
created_at: array[0].substring(1),
|
|
900
|
+
transactionid: array[5].substring(1),
|
|
901
|
+
[`${[prefix, 'order_id'].filter(Boolean).join('_')}`]: order_id,
|
|
902
|
+
openid: array[7].substring(1),
|
|
903
|
+
price: Number(array[12].substring(1)),
|
|
904
|
+
refund_price: Number(array[16].substring(1)),
|
|
905
|
+
remark: array[20].substring(1),
|
|
906
|
+
rate_price: Number(array[22].substring(1)),
|
|
907
|
+
type: array[9].substring(1),
|
|
908
|
+
order_date,
|
|
909
|
+
}
|
|
910
|
+
}),
|
|
911
|
+
totalHeader: arr[arr.length - 3],
|
|
912
|
+
total: arr[arr.length - 2],
|
|
913
|
+
totalResult: {
|
|
914
|
+
number: Number(arr[arr.length - 2].split(',')[0].substring(1)),
|
|
915
|
+
total_price: Number(arr[arr.length - 2].split(',')[1].substring(1)),
|
|
916
|
+
refund_price: Number(arr[arr.length - 2].split(',')[2].substring(1)),
|
|
917
|
+
rate_price: Number(arr[arr.length - 2].split(',')[4].substring(1)),
|
|
918
|
+
price: Number(arr[arr.length - 2].split(',')[5].substring(1)),
|
|
919
|
+
},
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
869
923
|
exports.downloadBill = async ({ ctx, pay_config = 'weixin_pay', ...rest }) => {
|
|
870
924
|
if (!ctx) throw new Error('?ctx')
|
|
871
925
|
const { app, appName } = getAppByCtx(ctx)
|
|
@@ -887,58 +941,17 @@ exports.downloadBill = async ({ ctx, pay_config = 'weixin_pay', ...rest }) => {
|
|
|
887
941
|
|
|
888
942
|
try {
|
|
889
943
|
const result = await payObj.downloadBill(rest)
|
|
944
|
+
return handleBillData(result)
|
|
945
|
+
} catch {
|
|
946
|
+
return []
|
|
947
|
+
}
|
|
948
|
+
}
|
|
890
949
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
result: list.map((item) => {
|
|
897
|
-
const array = item.split(',')
|
|
898
|
-
const orderdate = array[20].substring(1).slice(2, 10)
|
|
899
|
-
const orderPrefix = array[6].substring(1).split('_')[1]
|
|
900
|
-
let order_id = 0
|
|
901
|
-
let prefix = ''
|
|
902
|
-
if (orderPrefix.includes('-')) {
|
|
903
|
-
order_id = Number(orderPrefix.split('-')[1])
|
|
904
|
-
prefix = orderPrefix.split('-')[0]
|
|
905
|
-
} else {
|
|
906
|
-
order_id = Number(orderPrefix)
|
|
907
|
-
}
|
|
908
|
-
let order_date
|
|
909
|
-
if (prefix) {
|
|
910
|
-
order_date = moment(array[0].substring(1)).format('YYYY-MM-DD') + ''
|
|
911
|
-
} else {
|
|
912
|
-
order_date = moment(
|
|
913
|
-
`${orderdate.slice(0, 4)}-${orderdate.slice(
|
|
914
|
-
4,
|
|
915
|
-
6
|
|
916
|
-
)}-${orderdate.slice(6, 8)}`
|
|
917
|
-
).format('YYYY-MM-DD')
|
|
918
|
-
}
|
|
919
|
-
return {
|
|
920
|
-
created_at: array[0].substring(1),
|
|
921
|
-
transactionid: array[5].substring(1),
|
|
922
|
-
[`${[prefix, 'order_id'].filter(Boolean).join('_')}`]: order_id,
|
|
923
|
-
openid: array[7].substring(1),
|
|
924
|
-
price: Number(array[12].substring(1)),
|
|
925
|
-
refund_price: Number(array[16].substring(1)),
|
|
926
|
-
remark: array[20].substring(1),
|
|
927
|
-
rate_price: Number(array[22].substring(1)),
|
|
928
|
-
type: array[9].substring(1),
|
|
929
|
-
order_date,
|
|
930
|
-
}
|
|
931
|
-
}),
|
|
932
|
-
totalHeader: arr[arr.length - 3],
|
|
933
|
-
total: arr[arr.length - 2],
|
|
934
|
-
totalResult: {
|
|
935
|
-
number: Number(arr[arr.length - 2].split(',')[0].substring(1)),
|
|
936
|
-
total_price: Number(arr[arr.length - 2].split(',')[1].substring(1)),
|
|
937
|
-
refund_price: Number(arr[arr.length - 2].split(',')[2].substring(1)),
|
|
938
|
-
rate_price: Number(arr[arr.length - 2].split(',')[4].substring(1)),
|
|
939
|
-
price: Number(arr[arr.length - 2].split(',')[5].substring(1)),
|
|
940
|
-
},
|
|
941
|
-
}
|
|
950
|
+
exports.uploadBill = async ({ ctx, content }) => {
|
|
951
|
+
if (!ctx) throw new Error('?ctx')
|
|
952
|
+
if (!content) return []
|
|
953
|
+
try {
|
|
954
|
+
return handleBillData(content)
|
|
942
955
|
} catch {
|
|
943
956
|
return []
|
|
944
957
|
}
|
|
@@ -65,6 +65,12 @@ const getShipTemplateUrl =
|
|
|
65
65
|
const uploadShipUrl =
|
|
66
66
|
'https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=%s'
|
|
67
67
|
|
|
68
|
+
const uploadPreShipUrl =
|
|
69
|
+
'https://api.weixin.qq.com/wxa/sec/order/opspecialorder?access_token=%s'
|
|
70
|
+
|
|
71
|
+
const getShipOrderListUrl =
|
|
72
|
+
'https://api.weixin.qq.com/wxa/sec/order/get_order_list?access_token=%s'
|
|
73
|
+
|
|
68
74
|
const setMsgJumpPathUrl =
|
|
69
75
|
'https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path?access_token=%s'
|
|
70
76
|
|
|
@@ -117,6 +123,20 @@ const uploadPromise = (options) => {
|
|
|
117
123
|
})
|
|
118
124
|
}
|
|
119
125
|
|
|
126
|
+
const https = require('https')
|
|
127
|
+
|
|
128
|
+
// 1. 全局 HTTPS 连接池(微信专用)
|
|
129
|
+
const wxHttpsAgent = new https.Agent({
|
|
130
|
+
keepAlive: true, // 开启长连接
|
|
131
|
+
keepAliveMsecs: 60000, // 空闲连接保留 60 秒
|
|
132
|
+
maxSockets: 30, // 最大并发连接(适配微信QPS,不超限)
|
|
133
|
+
maxFreeSockets: 10, // 保留空闲连接数
|
|
134
|
+
timeout: 8000, // 底层套接字超时
|
|
135
|
+
rejectUnauthorized: true,
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
axios.defaults.httpsAgent = wxHttpsAgent
|
|
139
|
+
|
|
120
140
|
module.exports = class Singleton {
|
|
121
141
|
constructor(config) {
|
|
122
142
|
this.config = {
|
|
@@ -786,6 +806,44 @@ module.exports = class Singleton {
|
|
|
786
806
|
return result
|
|
787
807
|
}
|
|
788
808
|
|
|
809
|
+
async uploadPreShip(payLoad) {
|
|
810
|
+
const access_token = await this.getAccessToken()
|
|
811
|
+
const url = util.format(uploadPreShipUrl, access_token)
|
|
812
|
+
|
|
813
|
+
const result = await axios
|
|
814
|
+
.post(url, {
|
|
815
|
+
...payLoad,
|
|
816
|
+
})
|
|
817
|
+
.then((res) => res.data)
|
|
818
|
+
if (result.errcode) {
|
|
819
|
+
if (result.errcode === 40001) {
|
|
820
|
+
cache.reset()
|
|
821
|
+
return await this.uploadPreShip(payLoad)
|
|
822
|
+
}
|
|
823
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
824
|
+
}
|
|
825
|
+
return result
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
async getShipOrderList(payLoad) {
|
|
829
|
+
const access_token = await this.getAccessToken()
|
|
830
|
+
const url = util.format(getShipOrderListUrl, access_token)
|
|
831
|
+
|
|
832
|
+
const result = await axios
|
|
833
|
+
.post(url, {
|
|
834
|
+
...payLoad,
|
|
835
|
+
})
|
|
836
|
+
.then((res) => res.data)
|
|
837
|
+
if (result.errcode) {
|
|
838
|
+
if (result.errcode === 40001) {
|
|
839
|
+
cache.reset()
|
|
840
|
+
return await this.getShipOrderList(payLoad)
|
|
841
|
+
}
|
|
842
|
+
throw new Error(`${result.errcode};${result.errmsg}`)
|
|
843
|
+
}
|
|
844
|
+
return result
|
|
845
|
+
}
|
|
846
|
+
|
|
789
847
|
async uploadImage(payLoad) {
|
|
790
848
|
const access_token = await this.getAccessToken()
|
|
791
849
|
const { upload_type, resp_type, ...rest } = payLoad
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
const util = require('util')
|
|
2
2
|
const axios = require('axios')
|
|
3
|
+
const https = require('https')
|
|
4
|
+
// 1. 全局 HTTPS 连接池(微信专用)
|
|
5
|
+
const wxHttpsAgent = new https.Agent({
|
|
6
|
+
keepAlive: true, // 开启长连接
|
|
7
|
+
keepAliveMsecs: 60000, // 空闲连接保留 60 秒
|
|
8
|
+
maxSockets: 30, // 最大并发连接(适配微信QPS,不超限)
|
|
9
|
+
maxFreeSockets: 10, // 保留空闲连接数
|
|
10
|
+
timeout: 8000, // 底层套接字超时
|
|
11
|
+
rejectUnauthorized: true,
|
|
12
|
+
})
|
|
3
13
|
|
|
14
|
+
axios.defaults.httpsAgent = wxHttpsAgent
|
|
4
15
|
const { lodash } = require('q-koa')
|
|
5
16
|
const getAccessTokenUrl =
|
|
6
17
|
'https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s'
|