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.
- package/core/app.js +1813 -0
- package/core/config.js +124 -0
- package/core/file/plugins/administrator/config.js +17 -0
- package/core/file/plugins/administrator/controller.js +264 -0
- package/core/file/plugins/administrator/model.js +53 -0
- package/core/file/plugins/administrator/validate.js +41 -0
- package/core/file/plugins/alipay/controller.js +68 -0
- package/core/file/plugins/alipay/validate.js +9 -0
- package/core/file/plugins/cache/service.js +16 -0
- package/core/file/plugins/cloudfunction/config.js +4 -0
- package/core/file/plugins/cloudfunction/model.js +15 -0
- package/core/file/plugins/common/controller.js +398 -0
- package/core/file/plugins/common/validate.js +47 -0
- package/core/file/plugins/douyin/config.js +3 -0
- package/core/file/plugins/douyin/controller.js +521 -0
- package/core/file/plugins/douyin/validate.js +40 -0
- package/core/file/plugins/douyin_user/config.js +15 -0
- package/core/file/plugins/douyin_user/model.js +72 -0
- package/core/file/plugins/good_sku/controller.js +80 -0
- package/core/file/plugins/h5_user/config.js +19 -0
- package/core/file/plugins/h5_user/model.js +71 -0
- package/core/file/plugins/lang/config.js +4 -0
- package/core/file/plugins/lang/model.js +15 -0
- package/core/file/plugins/language/config.js +5 -0
- package/core/file/plugins/language/model.js +54 -0
- package/core/file/plugins/log/config.js +25 -0
- package/core/file/plugins/log/controller.js +31 -0
- package/core/file/plugins/log/model.js +51 -0
- package/core/file/plugins/model/config.js +12 -0
- package/core/file/plugins/model/controller.js +69 -0
- package/core/file/plugins/model/model.js +169 -0
- package/core/file/plugins/model/service.js +218 -0
- package/core/file/plugins/model/validate.js +42 -0
- package/core/file/plugins/model_attributes/config.js +12 -0
- package/core/file/plugins/model_attributes/model.js +114 -0
- package/core/file/plugins/mp_user/config.js +19 -0
- package/core/file/plugins/mp_user/model.js +59 -0
- package/core/file/plugins/permission/config.js +15 -0
- package/core/file/plugins/permission/model.js +91 -0
- package/core/file/plugins/role/config.js +27 -0
- package/core/file/plugins/role/controller.js +26 -0
- package/core/file/plugins/role/model.js +58 -0
- package/core/file/plugins/role_permission/config.js +12 -0
- package/core/file/plugins/role_permission/controller.js +27 -0
- package/core/file/plugins/role_permission/model.js +24 -0
- package/core/file/plugins/routes/config.js +17 -0
- package/core/file/plugins/routes/controller.js +153 -0
- package/core/file/plugins/routes/model.js +70 -0
- package/core/file/plugins/routes/service.js +22 -0
- package/core/file/plugins/setting/afterExecute.js +14 -0
- package/core/file/plugins/setting/config.js +14 -0
- package/core/file/plugins/setting/controller.js +50 -0
- package/core/file/plugins/setting/model.js +118 -0
- package/core/file/plugins/setting/validate.js +42 -0
- package/core/file/plugins/system/controller.js +501 -0
- package/core/file/plugins/system/service.js +148 -0
- package/core/file/plugins/system/validate.js +40 -0
- package/core/file/plugins/todolist/config.js +31 -0
- package/core/file/plugins/todolist/model.js +69 -0
- package/core/file/plugins/toutiao/controller.js +201 -0
- package/core/file/plugins/toutiao_user/config.js +15 -0
- package/core/file/plugins/toutiao_user/model.js +66 -0
- package/core/file/plugins/user/afterExecute.js +38 -0
- package/core/file/plugins/user/config.js +9 -0
- package/core/file/plugins/user/controller.js +329 -0
- package/core/file/plugins/user/model.js +96 -0
- package/core/file/plugins/user/test.js +71 -0
- package/core/file/plugins/user/validate.js +44 -0
- package/core/file/plugins/video/config.js +3 -0
- package/core/file/plugins/video/controller.js +15 -0
- package/core/file/plugins/video/validate.js +12 -0
- package/core/file/plugins/weixin/config.js +3 -0
- package/core/file/plugins/weixin/controller.js +994 -0
- package/core/file/plugins/weixin/service.js +105 -0
- package/core/file/plugins/weixin/validate.js +111 -0
- package/core/file/services/aliSms.js +45 -0
- package/core/file/services/alipay.js +123 -0
- package/core/file/services/amap.js +95 -0
- package/core/file/services/card.js +24 -0
- package/core/file/services/config.js +38 -0
- package/core/file/services/douyin.js +151 -0
- package/core/file/services/email.js +45 -0
- package/core/file/services/express.js +37 -0
- package/core/file/services/geo.js +71 -0
- package/core/file/services/qqVideo.js +64 -0
- package/core/file/services/toutiao.js +102 -0
- package/core/file/services/weixin.js +79 -0
- package/core/file/services/weixinArticle.js +53 -0
- package/core/file/services/weixinCrypt.js +34 -0
- package/core/file/services/weixinMP.js +435 -0
- package/core/file/services/weixinPay.js +35 -0
- package/core/file/services/xml.js +33 -0
- package/core/file/task/shop/index.js +589 -0
- package/core/file/task/shop/static/562e45760a44632de6fa7219bab78cce.png +0 -0
- package/core/file/task/shop/static/d7aeaeb6bfd68f71a00a83c0f5548363.png +0 -0
- package/core/file/utils/index.js +61 -0
- package/core/middlewares.js +120 -0
- package/core/restc/.npminstall.done +1 -0
- package/core/restc/LICENSE +21 -0
- package/core/restc/README.md +48 -0
- package/core/restc/faas/index.html +1112 -0
- package/core/restc/faas/index.txt +31 -0
- package/core/restc/faas/install_production.sh +6 -0
- package/core/restc/index.d.ts +7 -0
- package/core/restc/index.js +9 -0
- package/core/restc/lib/express.js +7 -0
- package/core/restc/lib/hapi.js +17 -0
- package/core/restc/lib/hapiLegacy.js +15 -0
- package/core/restc/lib/index.js +46 -0
- package/core/restc/lib/koa.js +9 -0
- package/core/restc/lib/koa2.js +9 -0
- package/core/restc/lib/utils/gateway.js +51 -0
- package/core/restc/package.json +41 -0
- package/core/validator.js +15 -0
- package/index.js +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const crypto = require('crypto')
|
|
4
|
+
const { Random, lodash, getAppByCtx, getConfig } = require('multiple-quick-koa')
|
|
5
|
+
const Captchapng = require('captchapng')
|
|
6
|
+
const qr = require('qr-image')
|
|
7
|
+
const OSS = require('ali-oss')
|
|
8
|
+
const axios = require('axios')
|
|
9
|
+
const util = require('util')
|
|
10
|
+
const jwt = require('jsonwebtoken')
|
|
11
|
+
|
|
12
|
+
const Email = require('../../services/email')
|
|
13
|
+
const Geo = require('../../services/geo')
|
|
14
|
+
|
|
15
|
+
const annotationsReg = /(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g
|
|
16
|
+
const apiReg = /@api(Name|Desc|Param|Route|Return)(\s+)(.*)\n/g
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @apiRoute upload
|
|
20
|
+
* @apiName 上传
|
|
21
|
+
* @apiParam subject/string/付款名称
|
|
22
|
+
* @apiParam total_fee/string/支付金额
|
|
23
|
+
* @apiReturn {url}
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
exports.upload = async (ctx) => {
|
|
27
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
28
|
+
|
|
29
|
+
if (!(ctx.request.files && ctx.request.files.file)) {
|
|
30
|
+
throw new Error('请选择上传文件')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { file, option = 'url' } = ctx.request.files
|
|
34
|
+
|
|
35
|
+
const appConfig = getConfig(app)
|
|
36
|
+
|
|
37
|
+
const { site_host } = await appConfig.getObject('base')
|
|
38
|
+
|
|
39
|
+
const reader = fs.readFileSync(file.path)
|
|
40
|
+
|
|
41
|
+
const fsHash = crypto.createHash('md5')
|
|
42
|
+
fsHash.update(reader)
|
|
43
|
+
const md5 = fsHash.digest('hex')
|
|
44
|
+
const newFilename = `${md5}.${
|
|
45
|
+
file.name.split('.')[file.name.split('.').length - 1]
|
|
46
|
+
}`
|
|
47
|
+
|
|
48
|
+
const imgData = Buffer.from(reader).toString('base64')
|
|
49
|
+
// 转换为 data:image/jpeg;base64,***** 格式的字符串
|
|
50
|
+
const base64 = `data:${file.name.split('.')[1]};base64,${imgData}`
|
|
51
|
+
|
|
52
|
+
// const { dir, upload } = app.config.static;
|
|
53
|
+
const targetPath = `${path.resolve(
|
|
54
|
+
__dirname,
|
|
55
|
+
`${process.cwd()}/public/upload`
|
|
56
|
+
)}/${newFilename}`
|
|
57
|
+
|
|
58
|
+
const isExists = fs.existsSync(targetPath)
|
|
59
|
+
const responseData = lodash.pick(
|
|
60
|
+
{
|
|
61
|
+
url: `//${site_host || 'api.kuashou.com'}/upload/${newFilename}`,
|
|
62
|
+
base64,
|
|
63
|
+
card: imgData,
|
|
64
|
+
},
|
|
65
|
+
[option]
|
|
66
|
+
)
|
|
67
|
+
if (isExists) return ctx.SUCCESS(responseData)
|
|
68
|
+
|
|
69
|
+
fs.writeFileSync(targetPath, reader)
|
|
70
|
+
return ctx.SUCCESS(responseData)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
exports.oss_upload = async (ctx) => {
|
|
74
|
+
const { app } = getAppByCtx(ctx)
|
|
75
|
+
|
|
76
|
+
if (
|
|
77
|
+
!(ctx.request.files && ctx.request.files.file) &&
|
|
78
|
+
!(ctx.request.body.url && ctx.request.body.filename)
|
|
79
|
+
) {
|
|
80
|
+
ctx.status = 500
|
|
81
|
+
ctx.ERROR('请选择上传文件')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const appConfig = getConfig(app)
|
|
85
|
+
|
|
86
|
+
const {
|
|
87
|
+
accessKeyId,
|
|
88
|
+
accessKeySecret,
|
|
89
|
+
bucket,
|
|
90
|
+
region,
|
|
91
|
+
cdn_host,
|
|
92
|
+
oss_host,
|
|
93
|
+
} = await appConfig.getObject('oss')
|
|
94
|
+
|
|
95
|
+
if (!(accessKeyId && accessKeySecret && bucket && region)) {
|
|
96
|
+
throw new Error('没有配置oss设置')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const client = new OSS({
|
|
100
|
+
accessKeyId,
|
|
101
|
+
accessKeySecret,
|
|
102
|
+
bucket,
|
|
103
|
+
region,
|
|
104
|
+
secure: true,
|
|
105
|
+
})
|
|
106
|
+
let fileName
|
|
107
|
+
let imageData
|
|
108
|
+
if (ctx.request.files && ctx.request.files.file) {
|
|
109
|
+
const { file } = ctx.request.files
|
|
110
|
+
fileName = `${
|
|
111
|
+
String(new Date().getTime()).split('').reverse().join('') + Math.random()
|
|
112
|
+
}.${file.name.split('.')[file.name.split('.').length - 1]}`
|
|
113
|
+
imageData = file.path
|
|
114
|
+
} else {
|
|
115
|
+
const { url: imageUrl, filename: imageFileName } = ctx.request.body
|
|
116
|
+
fileName = imageFileName
|
|
117
|
+
const formatUrl = imageUrl.startsWith('//') ? 'http:' + imageUrl : imageUrl
|
|
118
|
+
try {
|
|
119
|
+
imageData = await axios
|
|
120
|
+
.get(formatUrl, {
|
|
121
|
+
responseType: 'arraybuffer',
|
|
122
|
+
})
|
|
123
|
+
.then((res) => res.data)
|
|
124
|
+
} catch (e) {
|
|
125
|
+
ctx.status = 500
|
|
126
|
+
ctx.ERROR('请求图片错误')
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const result = await client.put(fileName, imageData)
|
|
130
|
+
if (result.res && result.res.status === 200) {
|
|
131
|
+
if (oss_host && cdn_host) {
|
|
132
|
+
const url = result.url.replace(oss_host, cdn_host)
|
|
133
|
+
return ctx.SUCCESS({
|
|
134
|
+
url,
|
|
135
|
+
})
|
|
136
|
+
} else {
|
|
137
|
+
const url = result.url
|
|
138
|
+
return ctx.SUCCESS({
|
|
139
|
+
url,
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
throw new Error(result.res.statusMessage)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
exports.captcha = async (ctx) => {
|
|
148
|
+
const number = Random.string('number', 4)
|
|
149
|
+
const p = new Captchapng(80, 30, number) // width,height,numeric captcha
|
|
150
|
+
p.color(0, 0, 0, 0) // First color: background (red, green, blue, alpha)
|
|
151
|
+
p.color(80, 80, 80, 255) // Second color: paint (red, green, blue, alpha)
|
|
152
|
+
|
|
153
|
+
const img = p.getBase64()
|
|
154
|
+
ctx.SUCCESS({
|
|
155
|
+
img: `data:image/png;base64,${img}`,
|
|
156
|
+
result: number,
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
exports.email = async (ctx) => {
|
|
161
|
+
const email = new Email({
|
|
162
|
+
email: '40854@qq.com',
|
|
163
|
+
password: 'xszvtgcjjqogcahb',
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
const { to, subject, text, html } = ctx.request.body
|
|
167
|
+
|
|
168
|
+
await email.send({
|
|
169
|
+
to,
|
|
170
|
+
subject,
|
|
171
|
+
text,
|
|
172
|
+
html,
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
return ctx.SUCCESS()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
exports.createQr = async (ctx) => {
|
|
179
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
180
|
+
|
|
181
|
+
const { url } = ctx.request.query
|
|
182
|
+
const img = qr.image(url, {
|
|
183
|
+
size: 10,
|
|
184
|
+
})
|
|
185
|
+
ctx.type = 'image/png'
|
|
186
|
+
ctx.body = img
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
exports.channel = async (ctx) => {
|
|
190
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
191
|
+
|
|
192
|
+
const channelId = ctx.query.channelId
|
|
193
|
+
if (ctx.ws) {
|
|
194
|
+
app.ws[channelId] = await ctx.ws()
|
|
195
|
+
|
|
196
|
+
const send = (data) => app.ws[channelId].send(JSON.stringify(data))
|
|
197
|
+
const sendMessage = (content) => {
|
|
198
|
+
console.log('收到信息了')
|
|
199
|
+
const { type, payload } = content
|
|
200
|
+
send({
|
|
201
|
+
type,
|
|
202
|
+
payload: payload.message,
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
app.event.removeAllListeners()
|
|
207
|
+
app.event.on(channelId, sendMessage)
|
|
208
|
+
} else {
|
|
209
|
+
throw new Error('这是一个websocket url')
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
exports.swagger = async (ctx) => {
|
|
214
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
215
|
+
if (app.cache && app.cache.get('swagger'))
|
|
216
|
+
return ctx.SUCCESS(app.cache.get('swagger'))
|
|
217
|
+
|
|
218
|
+
const filePath = path.resolve(
|
|
219
|
+
__dirname,
|
|
220
|
+
`${process.cwd()}/app/${appName}/plugins`
|
|
221
|
+
)
|
|
222
|
+
const apis = []
|
|
223
|
+
const pathList = fs.readdirSync(filePath)
|
|
224
|
+
for (let i = 0; i < pathList.length; i++) {
|
|
225
|
+
const folder = pathList[i]
|
|
226
|
+
const isFolder = fs.lstatSync(path.resolve(filePath, folder)).isDirectory()
|
|
227
|
+
if (isFolder) {
|
|
228
|
+
const models = []
|
|
229
|
+
if (app.model[folder]) {
|
|
230
|
+
const result = await app.sequelize
|
|
231
|
+
.getQueryInterface()
|
|
232
|
+
.describeTable(folder)
|
|
233
|
+
Object.keys(result).forEach((attr) => {
|
|
234
|
+
models.push(lodash.merge(app.attributes[folder][attr], result[attr]))
|
|
235
|
+
// models[attr] = lodash.merge(app.attributes[folder][attr], result[attr]);
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const controllers = []
|
|
240
|
+
const controllerFilePath = path.resolve(filePath, folder, 'controller.js')
|
|
241
|
+
const isControllerExist = fs.existsSync(controllerFilePath)
|
|
242
|
+
if (isControllerExist) {
|
|
243
|
+
const controllerFile = fs.readFileSync(controllerFilePath, 'utf-8')
|
|
244
|
+
const annotations = controllerFile.match(annotationsReg)
|
|
245
|
+
|
|
246
|
+
if (annotations) {
|
|
247
|
+
for (let j = 0; j < annotations.length; j++) {
|
|
248
|
+
const annotation = annotations[j]
|
|
249
|
+
let res
|
|
250
|
+
const obj = {}
|
|
251
|
+
while ((res = apiReg.exec(annotation))) {
|
|
252
|
+
res = res.map((item) => item.toLowerCase())
|
|
253
|
+
if (res[1] === 'param') {
|
|
254
|
+
const arr = res[3].split('/')
|
|
255
|
+
if (obj[res[1]]) {
|
|
256
|
+
obj[res[1]].push({
|
|
257
|
+
key: arr[0],
|
|
258
|
+
type: arr[1],
|
|
259
|
+
name: arr[2],
|
|
260
|
+
})
|
|
261
|
+
} else {
|
|
262
|
+
obj[res[1]] = []
|
|
263
|
+
|
|
264
|
+
obj[res[1]].push({
|
|
265
|
+
key: arr[0],
|
|
266
|
+
type: arr[1],
|
|
267
|
+
name: arr[2],
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
obj[res[1]] = res[3]
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
controllers.push(obj)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
apis.push({
|
|
279
|
+
name: folder,
|
|
280
|
+
desc: lodash.get(app, `config.${folder}.name`, `${folder}`),
|
|
281
|
+
models,
|
|
282
|
+
controllers,
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
app.cache && app.cache.set('swagger', apis)
|
|
287
|
+
// console.log(dir)
|
|
288
|
+
ctx.SUCCESS(apis)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
exports.getLocation = async (ctx) => {
|
|
292
|
+
const { app } = getAppByCtx(ctx)
|
|
293
|
+
|
|
294
|
+
const { provinceName, cityName, address } = ctx.request.body
|
|
295
|
+
if (!provinceName || !cityName || !address) {
|
|
296
|
+
return ctx.SUCCESS({
|
|
297
|
+
longitude: null,
|
|
298
|
+
latitude: null,
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
const appConfig = getConfig(app)
|
|
302
|
+
const { tencent_key } = await appConfig.getObject('map')
|
|
303
|
+
|
|
304
|
+
const geo = new Geo(tencent_key)
|
|
305
|
+
const addressName = address || `${provinceName}${cityName}`
|
|
306
|
+
const result = await geo.getToLngAndLat(addressName)
|
|
307
|
+
|
|
308
|
+
const { lng: longitude, lat: latitude } = result.location
|
|
309
|
+
|
|
310
|
+
return ctx.SUCCESS({
|
|
311
|
+
longitude,
|
|
312
|
+
latitude,
|
|
313
|
+
})
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
exports.getLngAndLat = async (ctx) => {
|
|
317
|
+
const { app } = getAppByCtx(ctx)
|
|
318
|
+
|
|
319
|
+
const { longitude, latitude } = ctx.request.body
|
|
320
|
+
|
|
321
|
+
const appConfig = getConfig(app)
|
|
322
|
+
const { tencent_key } = await appConfig.getObject('map')
|
|
323
|
+
|
|
324
|
+
const geo = new Geo(tencent_key)
|
|
325
|
+
const res = await geo.getToLoation({
|
|
326
|
+
longitude,
|
|
327
|
+
latitude,
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
return ctx.SUCCESS(res)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
exports.syncModel = async (ctx) => {
|
|
334
|
+
const { app } = getAppByCtx(ctx)
|
|
335
|
+
|
|
336
|
+
const { model: _model } = ctx.request.body
|
|
337
|
+
|
|
338
|
+
let modellist = []
|
|
339
|
+
if (_model === 'all') {
|
|
340
|
+
modellist = Object.keys(app.model)
|
|
341
|
+
} else {
|
|
342
|
+
modellist = [_model]
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
for (let index = 0; index < modellist.length; index++) {
|
|
346
|
+
const model = modellist[index]
|
|
347
|
+
try {
|
|
348
|
+
const list = await app.model[model].findAll({
|
|
349
|
+
raw: true,
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
const result = await app.sequelize
|
|
353
|
+
.getQueryInterface()
|
|
354
|
+
.describeTable(model)
|
|
355
|
+
|
|
356
|
+
const idType = result.id.type
|
|
357
|
+
|
|
358
|
+
if (idType.includes('TINYINT')) {
|
|
359
|
+
if (idType.includes('UNSIGNED') && list.length >= 128) {
|
|
360
|
+
throw new Error('id超过类型')
|
|
361
|
+
} else if (!idType.includes('UNSIGNED') && list.length >= 256) {
|
|
362
|
+
throw new Error('id超过类型')
|
|
363
|
+
}
|
|
364
|
+
} else if (idType.includes('SMALLINT')) {
|
|
365
|
+
if (idType.includes('UNSIGNED') && list.length >= 32767) {
|
|
366
|
+
throw new Error('id超过类型')
|
|
367
|
+
} else if (!idType.includes('UNSIGNED') && list.length >= 65535) {
|
|
368
|
+
throw new Error('id超过类型')
|
|
369
|
+
}
|
|
370
|
+
} else if (idType.includes('MEDIUMINT')) {
|
|
371
|
+
if (idType.includes('UNSIGNED') && list.length >= 8388607) {
|
|
372
|
+
throw new Error('id超过类型')
|
|
373
|
+
} else if (!idType.includes('UNSIGNED') && list.length >= 16777215) {
|
|
374
|
+
throw new Error('id超过类型')
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
await app.model[model].sync({
|
|
379
|
+
force: true,
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
await app.model[model].bulkCreate(list)
|
|
383
|
+
} catch (e) {
|
|
384
|
+
console.log(`${model}出错,${e.message}`)
|
|
385
|
+
continue
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
ctx.SUCCESS('ok')
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
exports.verify = async (ctx) => {
|
|
393
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
394
|
+
const { code } = ctx.request.body
|
|
395
|
+
const verify = util.promisify(jwt.verify)
|
|
396
|
+
const result = await verify(code, 'token')
|
|
397
|
+
ctx.SUCCESS(result)
|
|
398
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const { Validator } = require('multiple-quick-koa');
|
|
2
|
+
|
|
3
|
+
exports.email = async (ctx) => {
|
|
4
|
+
const params = {
|
|
5
|
+
to: {
|
|
6
|
+
type: 'string',
|
|
7
|
+
required: true,
|
|
8
|
+
message: '请输入接收邮箱',
|
|
9
|
+
},
|
|
10
|
+
subject: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
required: true,
|
|
13
|
+
message: '请输入邮件主题',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
await new Validator(params).validate(ctx.request.body);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.sendMessage = async ctx => {
|
|
20
|
+
const params = {
|
|
21
|
+
mobile: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
required: true,
|
|
24
|
+
validator: (rule, value) => {
|
|
25
|
+
return /^[1][1,2,3,4,5,7,8,9][0-9]{9}$/.test(value) ? Promise.resolve() : Promise.reject('请输入正确手机号');
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
await new Validator(params).validate(ctx.request.body);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
exports.schedule = async (ctx) => {
|
|
34
|
+
const params = {
|
|
35
|
+
to: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
required: true,
|
|
38
|
+
message: '请输入接收邮箱',
|
|
39
|
+
},
|
|
40
|
+
subject: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
required: true,
|
|
43
|
+
message: '请输入邮件主题',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
await new Validator(params).validate(ctx.request.body);
|
|
47
|
+
};
|