q-koa 7.7.2

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.
Files changed (116) hide show
  1. package/core/app.js +1813 -0
  2. package/core/config.js +124 -0
  3. package/core/file/plugins/administrator/config.js +17 -0
  4. package/core/file/plugins/administrator/controller.js +264 -0
  5. package/core/file/plugins/administrator/model.js +53 -0
  6. package/core/file/plugins/administrator/validate.js +41 -0
  7. package/core/file/plugins/alipay/controller.js +68 -0
  8. package/core/file/plugins/alipay/validate.js +9 -0
  9. package/core/file/plugins/cache/service.js +16 -0
  10. package/core/file/plugins/cloudfunction/config.js +4 -0
  11. package/core/file/plugins/cloudfunction/model.js +15 -0
  12. package/core/file/plugins/common/controller.js +398 -0
  13. package/core/file/plugins/common/validate.js +47 -0
  14. package/core/file/plugins/douyin/config.js +3 -0
  15. package/core/file/plugins/douyin/controller.js +521 -0
  16. package/core/file/plugins/douyin/validate.js +40 -0
  17. package/core/file/plugins/douyin_user/config.js +15 -0
  18. package/core/file/plugins/douyin_user/model.js +72 -0
  19. package/core/file/plugins/good_sku/controller.js +80 -0
  20. package/core/file/plugins/h5_user/config.js +19 -0
  21. package/core/file/plugins/h5_user/model.js +71 -0
  22. package/core/file/plugins/lang/config.js +4 -0
  23. package/core/file/plugins/lang/model.js +15 -0
  24. package/core/file/plugins/language/config.js +5 -0
  25. package/core/file/plugins/language/model.js +54 -0
  26. package/core/file/plugins/log/config.js +25 -0
  27. package/core/file/plugins/log/controller.js +31 -0
  28. package/core/file/plugins/log/model.js +51 -0
  29. package/core/file/plugins/model/config.js +12 -0
  30. package/core/file/plugins/model/controller.js +69 -0
  31. package/core/file/plugins/model/model.js +169 -0
  32. package/core/file/plugins/model/service.js +218 -0
  33. package/core/file/plugins/model/validate.js +42 -0
  34. package/core/file/plugins/model_attributes/config.js +12 -0
  35. package/core/file/plugins/model_attributes/model.js +114 -0
  36. package/core/file/plugins/mp_user/config.js +19 -0
  37. package/core/file/plugins/mp_user/model.js +59 -0
  38. package/core/file/plugins/permission/config.js +15 -0
  39. package/core/file/plugins/permission/model.js +91 -0
  40. package/core/file/plugins/role/config.js +27 -0
  41. package/core/file/plugins/role/controller.js +26 -0
  42. package/core/file/plugins/role/model.js +58 -0
  43. package/core/file/plugins/role_permission/config.js +12 -0
  44. package/core/file/plugins/role_permission/controller.js +27 -0
  45. package/core/file/plugins/role_permission/model.js +24 -0
  46. package/core/file/plugins/routes/config.js +17 -0
  47. package/core/file/plugins/routes/controller.js +153 -0
  48. package/core/file/plugins/routes/model.js +70 -0
  49. package/core/file/plugins/routes/service.js +22 -0
  50. package/core/file/plugins/setting/afterExecute.js +14 -0
  51. package/core/file/plugins/setting/config.js +14 -0
  52. package/core/file/plugins/setting/controller.js +50 -0
  53. package/core/file/plugins/setting/model.js +118 -0
  54. package/core/file/plugins/setting/validate.js +42 -0
  55. package/core/file/plugins/system/controller.js +501 -0
  56. package/core/file/plugins/system/service.js +148 -0
  57. package/core/file/plugins/system/validate.js +40 -0
  58. package/core/file/plugins/todolist/config.js +31 -0
  59. package/core/file/plugins/todolist/model.js +69 -0
  60. package/core/file/plugins/toutiao/controller.js +201 -0
  61. package/core/file/plugins/toutiao_user/config.js +15 -0
  62. package/core/file/plugins/toutiao_user/model.js +66 -0
  63. package/core/file/plugins/user/afterExecute.js +38 -0
  64. package/core/file/plugins/user/config.js +9 -0
  65. package/core/file/plugins/user/controller.js +329 -0
  66. package/core/file/plugins/user/model.js +96 -0
  67. package/core/file/plugins/user/test.js +71 -0
  68. package/core/file/plugins/user/validate.js +44 -0
  69. package/core/file/plugins/video/config.js +3 -0
  70. package/core/file/plugins/video/controller.js +15 -0
  71. package/core/file/plugins/video/validate.js +12 -0
  72. package/core/file/plugins/weixin/config.js +3 -0
  73. package/core/file/plugins/weixin/controller.js +994 -0
  74. package/core/file/plugins/weixin/service.js +105 -0
  75. package/core/file/plugins/weixin/validate.js +111 -0
  76. package/core/file/services/aliSms.js +45 -0
  77. package/core/file/services/alipay.js +123 -0
  78. package/core/file/services/amap.js +95 -0
  79. package/core/file/services/card.js +24 -0
  80. package/core/file/services/config.js +38 -0
  81. package/core/file/services/douyin.js +151 -0
  82. package/core/file/services/email.js +45 -0
  83. package/core/file/services/express.js +37 -0
  84. package/core/file/services/geo.js +71 -0
  85. package/core/file/services/qqVideo.js +64 -0
  86. package/core/file/services/toutiao.js +102 -0
  87. package/core/file/services/weixin.js +79 -0
  88. package/core/file/services/weixinArticle.js +53 -0
  89. package/core/file/services/weixinCrypt.js +34 -0
  90. package/core/file/services/weixinMP.js +435 -0
  91. package/core/file/services/weixinPay.js +35 -0
  92. package/core/file/services/xml.js +33 -0
  93. package/core/file/task/shop/index.js +589 -0
  94. package/core/file/task/shop/static/562e45760a44632de6fa7219bab78cce.png +0 -0
  95. package/core/file/task/shop/static/d7aeaeb6bfd68f71a00a83c0f5548363.png +0 -0
  96. package/core/file/utils/index.js +61 -0
  97. package/core/middlewares.js +120 -0
  98. package/core/restc/.npminstall.done +1 -0
  99. package/core/restc/LICENSE +21 -0
  100. package/core/restc/README.md +48 -0
  101. package/core/restc/faas/index.html +1112 -0
  102. package/core/restc/faas/index.txt +31 -0
  103. package/core/restc/faas/install_production.sh +6 -0
  104. package/core/restc/index.d.ts +7 -0
  105. package/core/restc/index.js +9 -0
  106. package/core/restc/lib/express.js +7 -0
  107. package/core/restc/lib/hapi.js +17 -0
  108. package/core/restc/lib/hapiLegacy.js +15 -0
  109. package/core/restc/lib/index.js +46 -0
  110. package/core/restc/lib/koa.js +9 -0
  111. package/core/restc/lib/koa2.js +9 -0
  112. package/core/restc/lib/utils/gateway.js +51 -0
  113. package/core/restc/package.json +41 -0
  114. package/core/validator.js +15 -0
  115. package/index.js +1 -0
  116. package/package.json +65 -0
@@ -0,0 +1,521 @@
1
+ const {
2
+ getAppByCtx,
3
+ getConfig,
4
+ lodash,
5
+ moment,
6
+ getService,
7
+ } = require('multiple-quick-koa')
8
+ const util = require('util')
9
+ const axios = require('axios')
10
+ const qr = require('qr-image')
11
+
12
+ const getCodeUrl =
13
+ 'https://open.douyin.com/platform/oauth/connect?client_key=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s'
14
+
15
+ const Douyin = getService('douyin')
16
+ const LRU = require('lru-cache')
17
+ const cache = new LRU({
18
+ max: 100,
19
+ maxAge: 1000 * 60 * 60,
20
+ })
21
+
22
+ /**
23
+ * @apiRoute login_callback
24
+ * @apiName 登录回调
25
+ * @apiParam code/string/code
26
+ * @apiParam state/string/user_id
27
+ * @apiReturn {null}
28
+ */
29
+ exports.login_callback = async (ctx) => {
30
+ const { app } = getAppByCtx(ctx)
31
+
32
+ const { code, state: user_id } = ctx.query
33
+ if (!code) {
34
+ return ctx.redirect(
35
+ 'https://doudou.kuashou.com/doudou/#/pages/accountFail/accountFail'
36
+ )
37
+ }
38
+
39
+ const appConfig = getConfig(app)
40
+ const { client_key, client_secret } = await appConfig.getObject('douyin')
41
+ const url = `https://open.douyin.com/oauth/access_token/?client_key=${client_key}&client_secret=${client_secret}&code=${code}&grant_type=authorization_code`
42
+
43
+ const codeResult = await axios.get(url).then((res) => res.data)
44
+
45
+ if (codeResult.message !== 'success') {
46
+ throw new Error(codeResult.data.description)
47
+ }
48
+ const { open_id, access_token } = codeResult.data
49
+ if (!open_id) throw new Error('抖音授权登录失败')
50
+
51
+ const checkExist = await app.model.douyin_user.findOne({
52
+ where: {
53
+ openid: open_id,
54
+ },
55
+ include: [
56
+ {
57
+ model: app.model.user,
58
+ include: app.model.h5_user,
59
+ },
60
+ ],
61
+ })
62
+
63
+ const errorObj = {
64
+ hasOther: checkExist
65
+ ? {
66
+ msg: '该抖音号已绑定过其他账户',
67
+ user: {
68
+ nick_name: checkExist.user.nick_name,
69
+ image: checkExist.user.image,
70
+ },
71
+ change_user_id: Number(user_id),
72
+ self_id: checkExist.id,
73
+ }
74
+ : null,
75
+ }
76
+
77
+ if (checkExist && checkExist.user_id !== Number(user_id)) {
78
+ return ctx.redirect(
79
+ `https://doudou.kuashou.com/doudou/#/pages/accountFail/accountFail?error=${encodeURIComponent(
80
+ JSON.stringify(errorObj.hasOther)
81
+ )}`
82
+ )
83
+ }
84
+
85
+ const userInfoUrl = `https://open.douyin.com/oauth/userinfo/?open_id=${open_id}&access_token=${access_token}`
86
+ const userInfoResult = await axios.get(userInfoUrl).then((res) => res.data)
87
+
88
+ if (userInfoResult.message !== 'success') {
89
+ throw new Error(userInfoResult.data.description)
90
+ }
91
+
92
+ // app.model.douyin_user.upsert({
93
+ // ...userInfoResult.data,
94
+ // openid: userInfoResult.data.open_id,
95
+ // nick_name: userInfoResult.data.nickname,
96
+ // })
97
+ const rest = userInfoResult.data
98
+ const post = lodash.pickBy(
99
+ {
100
+ nick_name: lodash.get(rest, 'nickname', null),
101
+ avatar: lodash.get(rest, 'avatar', null),
102
+ country: lodash.get(rest, 'country', null),
103
+ city: lodash.get(rest, 'city', null),
104
+ province: lodash.get(rest, 'province', null),
105
+ gender: lodash.get(rest, 'gender', null),
106
+ openid: rest.open_id,
107
+ user_id: user_id ? Number(user_id) : null,
108
+ access_token: access_token || '',
109
+ },
110
+ (item) => item !== null
111
+ )
112
+
113
+ const openIdUser = await app.model.douyin_user.findOne({
114
+ where: {
115
+ openid: post.openid,
116
+ },
117
+ })
118
+
119
+ let uid
120
+ if (openIdUser) {
121
+ await app.model.douyin_user.update(post, {
122
+ where: {
123
+ openid: post.openid,
124
+ },
125
+ })
126
+ uid = openIdUser.user_id
127
+ } else {
128
+ if (post.user_id) {
129
+ uid = post.user_id
130
+ } else {
131
+ const user = await app.model.user.create()
132
+ uid = user.id
133
+ }
134
+
135
+ await app.model.douyin_user.create({
136
+ ...post,
137
+ user_id: uid,
138
+ })
139
+ }
140
+
141
+ const result = await app.model.user.findOne({
142
+ where: {
143
+ id: uid,
144
+ },
145
+ include: [
146
+ {
147
+ model: app.model.h5_user,
148
+ },
149
+ {
150
+ model: app.model.douyin_user,
151
+ },
152
+ ...app.include.user,
153
+ ],
154
+ })
155
+
156
+ const tokenResult = {
157
+ id: result.id,
158
+ name: result.name,
159
+ mobile: result.mobile,
160
+ h5_user: result.h5_user
161
+ ? {
162
+ openid: result.h5_user && result.h5_user.openid,
163
+ }
164
+ : null,
165
+ douyin_users: result.douyin_users
166
+ ? result.douyin_users.map((item) => {
167
+ return {
168
+ openid: item && item.openid,
169
+ }
170
+ })
171
+ : [],
172
+ }
173
+
174
+ const token = await app.sign({
175
+ user: tokenResult,
176
+ })
177
+
178
+ // return ctx.SUCCESS({
179
+ // token,
180
+ // user: result
181
+ // })
182
+
183
+ return ctx.redirect(
184
+ 'https://doudou.kuashou.com/doudou/#/pages/accountSuccess/accountSuccess'
185
+ )
186
+ }
187
+
188
+ exports.createImg = async (ctx) => {
189
+ const { app, appName } = getAppByCtx(ctx)
190
+
191
+ const appConfig = getConfig(app)
192
+ const { client_key, host_link } = await appConfig.getObject('douyin')
193
+
194
+ const redirect_uri = `${host_link}/doudou/douyin/login_callback`
195
+ // const client_key = 'awrygfkjh7tts5rh'
196
+ // const scope = 'aweme.share,user_info,micapp.is_legal,video.create,video.delete,video.data,video.list,fans.data'
197
+
198
+ const scope =
199
+ 'aweme.share,user_info,micapp.is_legal,video.create,video.delete,video.data,video.list,fans.data'
200
+ const url = util.format(
201
+ getCodeUrl,
202
+ client_key,
203
+ redirect_uri,
204
+ scope,
205
+ ctx.query.user_id ? ctx.query.user_id : null
206
+ )
207
+ // const result = await axios.get(url, {
208
+ // client_key: app_id,
209
+ // }).then(res => res.data)
210
+ console.log('失败先检查client_key')
211
+ const img = qr.image(url, {
212
+ size: 2,
213
+ })
214
+ ctx.type = 'image/png'
215
+ ctx.body = img
216
+
217
+ // ctx.SUCCESS(result)
218
+ }
219
+
220
+ exports.fansData = async (ctx) => {
221
+ const { app } = getAppByCtx(ctx)
222
+
223
+ const { id } = ctx.request.body
224
+
225
+ const result = await app.model.douyin_user.findOne({
226
+ where: {
227
+ id,
228
+ },
229
+ })
230
+
231
+ if (!result) throw new Error('找不到用户')
232
+
233
+ const url = 'https://open.douyin.com/fans/data/?open_id=%s&access_token=%s'
234
+
235
+ const videoResult = await axios
236
+ .get(util.format(url, result.openid, result.access_token))
237
+ .then((res) => res.data)
238
+ if (videoResult.data.error_code) {
239
+ if (videoResult.data.error_code === 2190008) {
240
+ throw new Error('请重新授权')
241
+ }
242
+ throw new Error(videoResult.data.description)
243
+ }
244
+ ctx.SUCCESS(videoResult.data.fans_data)
245
+ }
246
+
247
+ exports.videoList = async (ctx) => {
248
+ const { app } = getAppByCtx(ctx)
249
+
250
+ const { id } = ctx.request.body
251
+
252
+ const result = await app.model.douyin_user.findOne({
253
+ where: {
254
+ id,
255
+ },
256
+ })
257
+
258
+ if (!result) throw new Error('找不到用户')
259
+
260
+ const url =
261
+ 'https://open.douyin.com/video/list/?open_id=%s&access_token=%s&count=%s'
262
+
263
+ const videoResult = await axios
264
+ .get(util.format(url, result.openid, result.access_token, 10))
265
+ .then((res) => res.data)
266
+ if (videoResult.data.error_code) {
267
+ if (videoResult.data.error_code === 2190008) {
268
+ throw new Error('请重新授权')
269
+ }
270
+ throw new Error(videoResult.data.description)
271
+ }
272
+ ctx.SUCCESS(videoResult.data.list)
273
+ }
274
+
275
+ const updateTask = async ({ app, list, active_time, douyin }) => {
276
+ if (list && list.length > 0) {
277
+ await Promise.all(
278
+ ['hot_search', 'hot_video'].map((item) => {
279
+ return app.model[item].sync({
280
+ force: true,
281
+ })
282
+ })
283
+ )
284
+
285
+ await app.model.hot_search.bulkCreate(
286
+ list.map((item) => {
287
+ const { sentence, hot_level } = item
288
+ return {
289
+ name: sentence,
290
+ level: hot_level,
291
+ created_at: active_time,
292
+ updated_at: active_time,
293
+ }
294
+ })
295
+ )
296
+
297
+ const newList = await app.model.hot_search.findAll({
298
+ limit: 3,
299
+ order: [['level', 'DESC']],
300
+ })
301
+ for (let i = 0; i < newList.length; i++) {
302
+ const { id, name } = newList[i]
303
+ // const {
304
+ // id
305
+ // } = await app.model.hot_search.create({
306
+ // name: sentence,
307
+ // level: hot_level,
308
+ // created_at: active_time,
309
+ // updated_at: active_time
310
+ // })
311
+ // console.log('生成' + id)
312
+ let videoItemList = []
313
+ if (i < 3) {
314
+ try {
315
+ const { list: videoList } = await douyin.getHotVideo(name)
316
+ videoItemList = [
317
+ ...videoItemList,
318
+ ...videoList.map((video) => {
319
+ const {
320
+ is_top,
321
+ share_url,
322
+ statistics,
323
+ create_time,
324
+ is_reviewed,
325
+ title,
326
+ video_status,
327
+ cover,
328
+ item_id,
329
+ } = video
330
+
331
+ const status = {
332
+ 1: '已发布',
333
+ 2: '不适宜公开',
334
+ 4: '审核中',
335
+ }
336
+ return {
337
+ hot_search_id: id,
338
+ image: cover,
339
+ is_top,
340
+ share_url,
341
+ play_count: statistics.play_count,
342
+ share_count: statistics.share_count,
343
+ comment_count: statistics.comment_count,
344
+ digg_count: statistics.digg_count,
345
+ download_count: statistics.download_count,
346
+ forward_count: statistics.forward_count,
347
+ created_at: moment(create_time * 1000),
348
+ is_reviewed,
349
+ name: title,
350
+ video_status: status[video_status],
351
+ itemid: item_id,
352
+ }
353
+ }),
354
+ ]
355
+ } catch (e) {
356
+ continue
357
+ }
358
+ }
359
+
360
+ await app.model.hot_video.bulkCreate(videoItemList)
361
+ }
362
+ }
363
+ }
364
+ exports.hotSearch = async (ctx) => {
365
+ const { app } = getAppByCtx(ctx)
366
+ console.log('33', 33)
367
+
368
+ const hotWord = await app.model.hot_search.findOne()
369
+ const minutes = hotWord
370
+ ? moment().diff(moment(hotWord.created_at), 'minutes')
371
+ : 1000
372
+
373
+ if (minutes < 30) {
374
+ console.log('离上次更新', minutes)
375
+ const result = await app.model.hot_search.findAll({
376
+ order: [['level', 'DESC']],
377
+ include: [
378
+ {
379
+ model: app.model.hot_video,
380
+ limit: 1,
381
+ where: {
382
+ image: {
383
+ $ne: '',
384
+ },
385
+ },
386
+ },
387
+ ],
388
+ })
389
+ ctx.SUCCESS(result)
390
+ return result
391
+ }
392
+
393
+ const appConfig = getConfig(app)
394
+
395
+ const { client_key, client_secret } = await appConfig.getObject('douyin')
396
+ const douyin = new Douyin({
397
+ client_key,
398
+ client_secret,
399
+ })
400
+
401
+ try {
402
+ const { active_time, list } = await douyin.getHotSearch()
403
+ updateTask({
404
+ app,
405
+ list,
406
+ active_time,
407
+ douyin,
408
+ })
409
+
410
+ const result = list.map((item) => {
411
+ return {
412
+ ...item,
413
+ name: item.sentence,
414
+ level: item.hot_level,
415
+ hot_videos: [],
416
+ created_at: active_time,
417
+ updated_at: active_time,
418
+ }
419
+ })
420
+ ctx.SUCCESS(result)
421
+ return result
422
+ } catch (e) {
423
+ console.log('ee')
424
+ const result = await app.model.hot_search.findAll({
425
+ order: [['level', 'DESC']],
426
+ include: [
427
+ {
428
+ model: app.model.hot_video,
429
+ limit: 1,
430
+ where: {
431
+ image: {
432
+ $ne: '',
433
+ },
434
+ },
435
+ },
436
+ ],
437
+ })
438
+
439
+ ctx.SUCCESS(result)
440
+ return result
441
+ }
442
+ }
443
+
444
+ exports.hotSearchTrending = async (ctx) => {
445
+ const { app } = getAppByCtx(ctx)
446
+
447
+ if (cache.get('hotSearchTrending')) {
448
+ return ctx.SUCCESS(cache.get('hotSearchTrending'))
449
+ }
450
+ const appConfig = getConfig(app)
451
+ const { client_key, client_secret } = await appConfig.getObject('douyin')
452
+ const douyin = new Douyin({
453
+ client_key,
454
+ client_secret,
455
+ })
456
+
457
+ try {
458
+ const result = await douyin.getHotSearchTrending()
459
+ cache.set('hotSearchTrending', result)
460
+ ctx.SUCCESS(result)
461
+ } catch (e) {
462
+ throw new Error(e.message)
463
+ }
464
+ }
465
+
466
+ exports.hotVideo = async (ctx) => {
467
+ const { app } = getAppByCtx(ctx)
468
+ const { word } = ctx.request.body
469
+ if (cache.get(word)) {
470
+ return ctx.SUCCESS(cache.get(word))
471
+ }
472
+
473
+ const appConfig = getConfig(app)
474
+ const { client_key, client_secret } = await appConfig.getObject('douyin')
475
+
476
+ const douyin = new Douyin({
477
+ client_key,
478
+ client_secret,
479
+ })
480
+ try {
481
+ const result = await douyin.getHotVideo(word)
482
+ cache.set(word, result)
483
+ ctx.SUCCESS(result)
484
+ } catch (e) {
485
+ throw new Error(e.message)
486
+ }
487
+ }
488
+
489
+ exports.starHot = async (ctx) => {
490
+ const { app } = getAppByCtx(ctx)
491
+
492
+ const {
493
+ // 达人热榜类型 * `1` - 星图指数榜 * `2` - 涨粉指数榜 * `3` - 性价比指数榜 * `4` - 种草指数榜 * `5` - 精选指数榜 * `6` - 传播指数榜
494
+ type = 1,
495
+ } = ctx.request.body
496
+ if (cache.get(`starHot-${type}`)) {
497
+ return ctx.SUCCESS(cache.get(`starHot-${type}`))
498
+ }
499
+ const appConfig = getConfig(app)
500
+ const { client_key, client_secret } = await appConfig.getObject('douyin')
501
+ console.log(client_key, 'client_key')
502
+ const douyin = new Douyin({
503
+ client_key,
504
+ client_secret,
505
+ })
506
+
507
+ const douyin1 = new Douyin({
508
+ client_key,
509
+ client_secret,
510
+ })
511
+
512
+ console.log('true', douyin1 === douyin)
513
+ try {
514
+ const result = await douyin.getStarHot(type)
515
+
516
+ cache.set(`starHot-${type}`, result)
517
+ ctx.SUCCESS(result)
518
+ } catch (e) {
519
+ throw new Error(e.message)
520
+ }
521
+ }
@@ -0,0 +1,40 @@
1
+ const { Validator } = require('multiple-quick-koa')
2
+ /**
3
+ *
4
+ * 详情 https://www.jianshu.com/p/2105c48b45c7
5
+ *
6
+ */
7
+ exports.hotVideo = async ctx => {
8
+ const params = {
9
+ word: {
10
+ type: 'string',
11
+ required: true,
12
+ message: '请输入热词',
13
+ },
14
+ };
15
+ await new Validator(params).validate(ctx.request.body);
16
+ };
17
+
18
+
19
+ exports.videoList = async ctx => {
20
+ const params = {
21
+ id: {
22
+ type: 'number',
23
+ required: true,
24
+ message: '请输入id',
25
+ },
26
+ };
27
+ await new Validator(params).validate(ctx.request.body);
28
+ };
29
+
30
+ exports.fansData = async ctx => {
31
+ const params = {
32
+ id: {
33
+ type: 'number',
34
+ required: true,
35
+ message: '请输入id',
36
+ },
37
+ };
38
+ await new Validator(params).validate(ctx.request.body);
39
+ };
40
+
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ name: '抖音平台用户',
3
+ belongs: 'page',
4
+ multiple: false,
5
+ availableSort: false,
6
+ order: ["created_at"],
7
+ select: [{"key":"user_id"},{"key":"nick_name"}],
8
+ excludes: [],
9
+ limit: 20,
10
+ defaultOrder: [{ sort: 'descending', type: 'id' }],
11
+ comment: {"created_at":"创建时间"},
12
+ sortOrder: 1,
13
+ reference: [],
14
+ excludeAuth: [],
15
+ }
@@ -0,0 +1,72 @@
1
+ const { Sequelize } = require('multiple-quick-koa')
2
+
3
+ exports.openid = {
4
+ type: Sequelize.STRING,
5
+ comment: 'openid',
6
+ allowNull: false,
7
+ unique: true,
8
+ }
9
+
10
+ exports.nick_name = {
11
+ type: Sequelize.STRING,
12
+ comment: '昵称',
13
+ allowNull: false,
14
+ defaultValue: '',
15
+ }
16
+
17
+ exports.gender = {
18
+ type: Sequelize.INTEGER(11),
19
+ allowNull: false,
20
+ defaultValue: 1,
21
+ comment: '性别',
22
+ }
23
+
24
+ exports.city = {
25
+ type: Sequelize.STRING,
26
+ comment: '城市',
27
+ allowNull: false,
28
+ defaultValue: '',
29
+ }
30
+
31
+ exports.province = {
32
+ type: Sequelize.STRING,
33
+ comment: '省份',
34
+ allowNull: false,
35
+ defaultValue: '',
36
+ }
37
+
38
+ exports.country = {
39
+ type: Sequelize.STRING,
40
+ comment: '国家',
41
+ allowNull: false,
42
+ defaultValue: '',
43
+ }
44
+
45
+ exports.avatar = {
46
+ type: Sequelize.STRING(1000),
47
+ comment: '头像',
48
+ allowNull: false,
49
+ defaultValue: '',
50
+ }
51
+
52
+ exports.name = {
53
+ type: Sequelize.VIRTUAL,
54
+ comment: '名字',
55
+ get: function () {
56
+ return this.getDataValue('nick_name')
57
+ },
58
+ }
59
+
60
+ exports.user_id = {
61
+ type: Sequelize.INTEGER(11),
62
+ allowNull: false,
63
+ defaultValue: 0,
64
+ comment: '用户',
65
+ }
66
+
67
+ exports.access_token = {
68
+ type: Sequelize.STRING,
69
+ comment: 'access token',
70
+ allowNull: false,
71
+ defaultValue: '',
72
+ }