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,329 @@
1
+ const md5 = require('js-md5')
2
+ const { getAppByCtx, getConfig } = require('multiple-quick-koa')
3
+
4
+ exports.login = async (ctx) => {
5
+ const { app, appName } = getAppByCtx(ctx)
6
+ const { mobile, password, ...rest } = ctx.request.body
7
+ let result = await app.model.user.findOne({
8
+ where: {
9
+ mobile,
10
+ password: [md5(password), password],
11
+ ...rest,
12
+ },
13
+ })
14
+ if (!result) throw new Error('账号密码错误')
15
+ console.log('user==>', ctx.request[`${appName}-user`])
16
+ if (
17
+ ctx.request[`${appName}-user`] &&
18
+ ctx.request[`${appName}-user`].mp_user
19
+ ) {
20
+ // 如果还有第三方账号app.model.xx_user,也有同样的分支逻辑
21
+
22
+ /**
23
+ * 绑定匿名用户,更新成当前用户
24
+ */
25
+
26
+ await app.model.mp_user.update(
27
+ {
28
+ user_id: result.id,
29
+ },
30
+ {
31
+ where: {
32
+ user_id: ctx.request[`${appName}-user`].id,
33
+ },
34
+ }
35
+ )
36
+ }
37
+
38
+ if (
39
+ ctx.request[`${appName}-user`] &&
40
+ ctx.request[`${appName}-user`].h5_user
41
+ ) {
42
+ await app.model.h5_user.update(
43
+ {
44
+ user_id: result.id,
45
+ },
46
+ {
47
+ where: {
48
+ user_id: ctx.request[`${appName}-user`].id,
49
+ },
50
+ }
51
+ )
52
+ }
53
+
54
+ if (
55
+ ctx.request[`${appName}-user`] &&
56
+ ctx.request[`${appName}-user`].github_user
57
+ ) {
58
+ await app.model.github_user.update(
59
+ {
60
+ user_id: result.id,
61
+ },
62
+ {
63
+ where: {
64
+ user_id: ctx.request[`${appName}-user`].id,
65
+ },
66
+ }
67
+ )
68
+ }
69
+ /**
70
+ * 查出最新用户,存token并返回
71
+ */
72
+ result = await app.model.user.findOne({
73
+ where: {
74
+ id: result.id,
75
+ },
76
+ include: [
77
+ {
78
+ model: app.model.github_user,
79
+ },
80
+ {
81
+ model: app.model.h5_user,
82
+ },
83
+ {
84
+ model: app.model.mp_user,
85
+ },
86
+ {
87
+ model: app.model.toutiao_user,
88
+ },
89
+ ...app.include.user,
90
+ ].filter((item) => item.model),
91
+ })
92
+
93
+ const tokenResult = {
94
+ id: result.id,
95
+ name: result.name,
96
+ mobile: result.mobile,
97
+ h5_user: result.h5_user
98
+ ? {
99
+ openid: result.h5_user && result.h5_user.openid,
100
+ }
101
+ : null,
102
+ mp_user: result.mp_user
103
+ ? {
104
+ openid: result.mp_user && result.mp_user.openid,
105
+ }
106
+ : null,
107
+ toutiao_user: result.toutiao_user
108
+ ? {
109
+ openid: result.toutiao_user && result.toutiao_user.openid,
110
+ }
111
+ : null,
112
+ }
113
+ const token = await app.sign({
114
+ user: tokenResult,
115
+ })
116
+
117
+ return ctx.SUCCESS({
118
+ token,
119
+ user: result,
120
+ })
121
+ }
122
+
123
+ exports.register = async (ctx) => {
124
+ const { app, appName } = getAppByCtx(ctx)
125
+ const { name, mobile, code, password } = ctx.request.body
126
+
127
+ const result = await app.model.user.findOne({
128
+ where: {
129
+ mobile,
130
+ code,
131
+ },
132
+ })
133
+
134
+ if (!result) {
135
+ throw new Error('手机号和验证码不一致')
136
+ }
137
+
138
+ if (
139
+ ctx.request[`${appName}-user`] &&
140
+ ctx.request[`${appName}-user`].mp_user
141
+ ) {
142
+ // 如果还有第三方账号app.model.xx_user,也有同样的分支逻辑
143
+
144
+ /**
145
+ * 绑定匿名用户,更新成当前用户
146
+ */
147
+
148
+ await app.model.mp_user.update(
149
+ {
150
+ user_id: result.id,
151
+ },
152
+ {
153
+ where: {
154
+ user_id: ctx.request[`${appName}-user`].id,
155
+ },
156
+ }
157
+ )
158
+ }
159
+
160
+ await app.model.user.update(
161
+ {
162
+ name,
163
+ password,
164
+ },
165
+ {
166
+ where: {
167
+ mobile,
168
+ },
169
+ }
170
+ )
171
+
172
+ const userResult = await app.model.user.findOne({
173
+ where: {
174
+ id: result.id,
175
+ },
176
+ include: [
177
+ {
178
+ model: app.model.h5_user,
179
+ },
180
+ {
181
+ model: app.model.mp_user,
182
+ },
183
+ ...app.include.user,
184
+ ].filter((item) => item.model),
185
+ })
186
+
187
+ const token = await app.sign({
188
+ user: userResult,
189
+ })
190
+
191
+ return ctx.SUCCESS({
192
+ token,
193
+ user: result,
194
+ })
195
+ }
196
+
197
+ exports.checkLogin = async (ctx) => {
198
+ const { app, appName } = getAppByCtx(ctx)
199
+ const { config: _config } = ctx.request.body
200
+ const config = _config || 'weixin_mp'
201
+ const appConfig = getConfig(app)
202
+ const { app_id } = await appConfig.getObject(config)
203
+ if (ctx.request[`${appName}-user`] && ctx.request[`${appName}-user`].id) {
204
+ const h5_user_include = config.includes('h5')
205
+ ? {
206
+ model: app.model.h5_user,
207
+ where: {
208
+ appid: app_id,
209
+ },
210
+ attributes: {
211
+ exclude: ['created_at', 'updated_at', 'createdid'],
212
+ },
213
+ }
214
+ : {
215
+ model: app.model.h5_user,
216
+ }
217
+ const mp_user_include = config.includes('mp')
218
+ ? {
219
+ model: app.model.mp_user,
220
+ where: {
221
+ appid: app_id,
222
+ },
223
+ }
224
+ : {
225
+ model: app.model.mp_user,
226
+ }
227
+ let result
228
+ const includeDefault = [
229
+ {
230
+ model: app.model.github_user,
231
+ },
232
+ h5_user_include,
233
+ mp_user_include,
234
+ {
235
+ model: app.model.toutiao_user,
236
+ },
237
+ ...app.include.user,
238
+ ].filter((item) => item.model)
239
+ if (app.appConfig.loginData) {
240
+ const include = includeDefault.filter((i) => {
241
+ return app.appConfig.loginData.excludeInclude.every((m) => {
242
+ return app.model[m] !== i.model
243
+ })
244
+ })
245
+ result = await app.model.user.findOne({
246
+ where: {
247
+ id: ctx.request[`${appName}-user`].id,
248
+ },
249
+ attributes: app.appConfig.loginData.attributes,
250
+ include,
251
+ })
252
+ } else {
253
+ result = await app.model.user.findOne({
254
+ where: {
255
+ id: ctx.request[`${appName}-user`].id,
256
+ },
257
+ include: includeDefault,
258
+ })
259
+ }
260
+
261
+ if (!result) {
262
+ return ctx.SUCCESS({
263
+ token: null,
264
+ user: null,
265
+ })
266
+ }
267
+
268
+ if (config.includes('mp')) {
269
+ const appConfig = getConfig(app)
270
+ const { app_id } = await appConfig.getObject(config)
271
+ if (
272
+ !result.mp_user ||
273
+ (result.mp_user.appid && result.mp_user.appid !== app_id)
274
+ ) {
275
+ return ctx.SUCCESS({
276
+ token: null,
277
+ user: null,
278
+ })
279
+ }
280
+ } else if (config.includes('h5')) {
281
+ const appConfig = getConfig(app)
282
+ const { app_id } = await appConfig.getObject(config)
283
+ if (
284
+ !result.h5_user ||
285
+ (result.h5_user.appid && result.h5_user.appid !== app_id)
286
+ ) {
287
+ return ctx.SUCCESS({
288
+ token: null,
289
+ user: null,
290
+ })
291
+ }
292
+ }
293
+
294
+ const tokenResult = {
295
+ id: result.id,
296
+ name: result.name,
297
+ mobile: result.mobile,
298
+ h5_user: result.h5_user
299
+ ? {
300
+ openid: result.h5_user && result.h5_user.openid,
301
+ }
302
+ : null,
303
+ mp_user: result.mp_user
304
+ ? {
305
+ openid: result.mp_user && result.mp_user.openid,
306
+ }
307
+ : null,
308
+ toutiao_user: result.toutiao_user
309
+ ? {
310
+ openid: result.toutiao_user && result.toutiao_user.openid,
311
+ }
312
+ : null,
313
+ }
314
+ const token = await app.sign({
315
+ user: tokenResult,
316
+ })
317
+
318
+ return ctx.SUCCESS({
319
+ token,
320
+ user: result,
321
+ })
322
+ }
323
+
324
+ return ctx.SUCCESS({
325
+ token: null,
326
+ user: null,
327
+ })
328
+ }
329
+ exports.logout = async (ctx) => ctx.SUCCESS()
@@ -0,0 +1,96 @@
1
+ const { Sequelize, Random } = require('multiple-quick-koa');
2
+ const md5 = require('js-md5');
3
+
4
+ exports.nick_name = {
5
+ type: Sequelize.STRING,
6
+ comment: '昵称',
7
+ allowNull: false,
8
+ is_mock: false,
9
+ defaultValue: '',
10
+ sortOrder: 1,
11
+ };
12
+ exports.name = {
13
+ type: Sequelize.STRING,
14
+ comment: '名字',
15
+ allowNull: false,
16
+ is_mock: true,
17
+ defaultValue: '',
18
+ sortOrder: 2,
19
+ mock: () => Random.word(5),
20
+ get: function () {
21
+ return this.getDataValue('nick_name') || (this.getDataValue('mp_user') && this.getDataValue('mp_user').nick_name) ||
22
+ (this.getDataValue('h5_user') && this.getDataValue('h5_user').nick_name) ||
23
+ (this.getDataValue('toutiao_user') && this.getDataValue('toutiao_user').nick_name) ||
24
+ '匿名用户'
25
+ },
26
+ };
27
+
28
+ exports.image = {
29
+ type: Sequelize.VIRTUAL,
30
+ comment: '注释',
31
+ allowNull: false,
32
+ is_mock: false,
33
+ defaultValue: '',
34
+ sortOrder: 3,
35
+ get: function () {
36
+ return this.getDataValue('avatar') || (this.getDataValue('mp_user') && this.getDataValue('mp_user').avatar) ||
37
+ (this.getDataValue('h5_user') && this.getDataValue('h5_user').avatar) ||
38
+ (this.getDataValue('toutiao_user') && this.getDataValue('toutiao_user').avatar) ||
39
+ '//p0.meituan.net/codeman/bc1b8f0172cf718719edfb130ba171912425.jpg@120w_120h_1c_1e'
40
+ },
41
+ };
42
+
43
+ exports.avatar = {
44
+ type: Sequelize.STRING,
45
+ comment: '头像',
46
+ allowNull: false,
47
+ defaultValue: '//p0.meituan.net/codeman/bc1b8f0172cf718719edfb130ba171912425.jpg@120w_120h_1c_1e',
48
+ mock: () => Random.image('100x100', Random.color(), Random.cword()),
49
+ };
50
+
51
+ exports.code = {
52
+ type: Sequelize.STRING(6),
53
+ allowNull: false,
54
+ comment: '验证码',
55
+ defaultValue: '',
56
+ mock: () => Random.string('number', 4),
57
+ };
58
+
59
+ exports.sex_id = {
60
+ type: Sequelize.INTEGER(11),
61
+ allowNull: false,
62
+ defaultValue: 4,
63
+ comment: '性别',
64
+ };
65
+
66
+ exports.password = {
67
+ type: Sequelize.STRING(),
68
+ allowNull: false,
69
+ comment: '密码',
70
+ defaultValue: '7b17d87eb787c51b4da25ec1bed26c8d',
71
+ set(value) {
72
+ this.setDataValue('password', md5(value))
73
+ }
74
+ // validate: {
75
+ // notNull: {
76
+ // msg: '密码不允许为空',
77
+ // },
78
+ // notEmpty: {
79
+ // msg: '密码不允许为空',
80
+ // },
81
+ // },
82
+ };
83
+
84
+ exports.mobile = {
85
+ type: Sequelize.STRING(),
86
+ allowNull: false,
87
+ comment: '手机',
88
+ defaultValue: '',
89
+ // validate: {
90
+ // is: {
91
+ // args: /^1[3456789]\d{9}$/,
92
+ // msg: '请输入手机号',
93
+ // },
94
+ // },
95
+ mock: () => Random.natural(13000000000, 19999999999),
96
+ };
@@ -0,0 +1,71 @@
1
+ const axios = require('axios');
2
+ const APP = require('multiple-quick-koa');
3
+ const APP_CONFIG = require('../../config');
4
+ const config = require('./config');
5
+
6
+ const modelName = __dirname.split('/').reverse()[0];
7
+ const service = axios.create({
8
+ baseURL: `http://localhost:${APP_CONFIG.port}/${modelName}`,
9
+ });
10
+ service.interceptors.request.use((config) => { config.headers['Client-Type'] = 2; return config; });
11
+
12
+ service.interceptors.response.use(response => response.data, error => Promise.reject(error));
13
+
14
+ const sleep = time => new Promise(resolve => setTimeout(resolve, time * 1000));
15
+
16
+ describe(`${config.name}/${modelName}`, () => {
17
+ beforeAll(async () => {
18
+ try {
19
+ await axios.post('/');
20
+ } catch (e) {
21
+ console.log('正在启动服务器');
22
+ const app = new APP(APP_CONFIG);
23
+ await app.start();
24
+ }
25
+ });
26
+
27
+ test('错误登录', async () => {
28
+ const res = await service.post('login', {
29
+ name: 'chenlin1',
30
+ password: 'sugar23',
31
+ });
32
+ expect(res.code).toBe(500);
33
+ });
34
+
35
+ test('正确登录', async () => {
36
+ const res = await service.post('login', {
37
+ name: 'chenlin',
38
+ password: 'sugar23',
39
+ });
40
+ expect(res.code).toBe(200);
41
+ });
42
+
43
+ test('获取token', async () => {
44
+ const { data: { token } } = await service.post('login', {
45
+ name: 'chenlin',
46
+ password: 'sugar23',
47
+ });
48
+ expect(Boolean(token)).toBe(true);
49
+ });
50
+
51
+ test('没有token信息', async () => {
52
+ const res = await service.post('getInfo', {});
53
+ expect(res.code).toBe(401);
54
+ });
55
+
56
+ test('获取用户信息', async () => {
57
+ const { data: { token } } = await service.post('login', {
58
+ name: 'chenlin',
59
+ password: 'sugar23',
60
+ });
61
+
62
+ const res = await service.post('getInfo', {}, {
63
+ headers: {
64
+ 'Client-Type': 2,
65
+ 'X-Token': token,
66
+ },
67
+ });
68
+
69
+ expect(res.code).toBe(200);
70
+ });
71
+ });
@@ -0,0 +1,44 @@
1
+ const { Validator } = require('multiple-quick-koa');
2
+
3
+ exports.login = async (ctx) => {
4
+ const params = {
5
+ mobile: {
6
+ type: 'string',
7
+ required: true,
8
+ message: '请输入手机号',
9
+ },
10
+ password: {
11
+ type: 'string',
12
+ required: true,
13
+ message: '请输入密码',
14
+ },
15
+ };
16
+ await new Validator(params).validate(ctx.request.body);
17
+ };
18
+
19
+
20
+ exports.register = async (ctx) => {
21
+ const params = {
22
+ mobile: {
23
+ type: 'string',
24
+ required: true,
25
+ message: '请输入手机号',
26
+ },
27
+ password: {
28
+ type: 'string',
29
+ required: true,
30
+ message: '请输入密码',
31
+ },
32
+ name: {
33
+ type: 'string',
34
+ required: true,
35
+ message: '请输入昵称',
36
+ },
37
+ code: {
38
+ type: 'string',
39
+ required: true,
40
+ message: '请输入昵称',
41
+ },
42
+ };
43
+ await new Validator(params).validate(ctx.request.body);
44
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ name: '视频',
3
+ };
@@ -0,0 +1,15 @@
1
+ const qqVideo = require('../../services/qqVideo')
2
+ const { getAppByCtx } = require('multiple-quick-koa')
3
+
4
+ exports.qq = async ctx => {
5
+ const { app, appName } = getAppByCtx(ctx)
6
+
7
+ const {
8
+ vid
9
+ } = ctx.request.body
10
+
11
+ const video = await qqVideo(vid)
12
+ // if (true) throw new Error('账号密码错误');
13
+
14
+ return ctx.SUCCESS(video)
15
+ }
@@ -0,0 +1,12 @@
1
+ const { Validator } = require('multiple-quick-koa');
2
+
3
+ exports.qq = async (ctx) => {
4
+ const params = {
5
+ vid: {
6
+ type: 'string',
7
+ required: true,
8
+ message: '请输入腾讯vid',
9
+ },
10
+ };
11
+ await new Validator(params).validate(ctx.request.body);
12
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ name: '微信相关',
3
+ };