moyan-api 1.0.1
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/.eslintrc.js +28 -0
- package/.gitee/ISSUE_TEMPLATE.zh-CN.md +13 -0
- package/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +11 -0
- package/.prettierrc +5 -0
- package/CHANGELOG.md +5 -0
- package/LICENSE +201 -0
- package/README.en.md +36 -0
- package/README.md +153 -0
- package/dist/apiv2/axios.d.ts +13 -0
- package/dist/apiv2/axios.js +69 -0
- package/dist/apiv2/axios.js.map +1 -0
- package/dist/apiv2/base.d.ts +43 -0
- package/dist/apiv2/base.js +93 -0
- package/dist/apiv2/base.js.map +1 -0
- package/dist/apiv2/config.d.ts +1 -0
- package/dist/apiv2/config.js +26 -0
- package/dist/apiv2/config.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/axios.d.ts +13 -0
- package/dist/lib/axios.js +71 -0
- package/dist/lib/axios.js.map +1 -0
- package/dist/lib/base.d.ts +48 -0
- package/dist/lib/base.js +95 -0
- package/dist/lib/base.js.map +1 -0
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.js +26 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/main.d.ts +15 -0
- package/dist/main.js +75 -0
- package/dist/main.js.map +1 -0
- package/dist/template/api.d.ts +16 -0
- package/dist/template/api.js +90 -0
- package/dist/template/api.js.map +1 -0
- package/dist/template/schemas.d.ts +13 -0
- package/dist/template/schemas.js +89 -0
- package/dist/template/schemas.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/mo.d.ts +28 -0
- package/dist/utils/mo.js +254 -0
- package/dist/utils/mo.js.map +1 -0
- package/package.json +38 -0
- package/src/index.ts +38 -0
- package/src/lib/base.ts +180 -0
- package/src/main.ts +90 -0
- package/src/template/api.ts +102 -0
- package/src/template/schemas.ts +89 -0
- package/src/utils/mo.ts +402 -0
- package/tsconfig.json +20 -0
- package/view/api.ejs +25 -0
- package/view/schemas.ejs +12 -0
package/src/utils/mo.ts
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
export class MoUtils {
|
|
2
|
+
private static _$mo: MoUtils
|
|
3
|
+
constructor() {
|
|
4
|
+
MoUtils._$mo = this
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
static get $mo() {
|
|
8
|
+
return MoUtils._$mo || new MoUtils()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async runTime(name: string, cb: () => Promise<any>) {
|
|
12
|
+
const start = new Date().getTime()
|
|
13
|
+
const res = await cb()
|
|
14
|
+
const end = new Date().getTime()
|
|
15
|
+
console.info(name, end - start)
|
|
16
|
+
return res
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 首字母大写
|
|
21
|
+
* @param str | 需要转换的字符串
|
|
22
|
+
* @param m | 是否出首字母外,全部转换小写
|
|
23
|
+
*/
|
|
24
|
+
public firstWordUpperCase(str: string, m = false): string {
|
|
25
|
+
if (m) {
|
|
26
|
+
str = str.toLowerCase()
|
|
27
|
+
}
|
|
28
|
+
return str.replace(/\b([\w|']+)\b/g, function (word) {
|
|
29
|
+
return word.replace(word.charAt(0), word.charAt(0).toUpperCase())
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 首字母小写
|
|
35
|
+
* @param str | 需要转换的字符串
|
|
36
|
+
* @param m | 是否出首字母外,全部转换小写
|
|
37
|
+
*/
|
|
38
|
+
public firstWordLowerCase(str: string, m = false): string {
|
|
39
|
+
if (m) {
|
|
40
|
+
str = str.toLowerCase()
|
|
41
|
+
}
|
|
42
|
+
return str.replace(/\b([\w|']+)\b/g, function (word) {
|
|
43
|
+
return word.replace(word.charAt(0), word.charAt(0).toLowerCase())
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 深度克隆对象
|
|
49
|
+
* @param obj any | 对象或者数组
|
|
50
|
+
* @return {*} 新的对象
|
|
51
|
+
*/
|
|
52
|
+
public clone<T>(obj: T): T {
|
|
53
|
+
if (typeof obj !== "object") return obj
|
|
54
|
+
if (obj == null) return obj
|
|
55
|
+
let myNewObj: any
|
|
56
|
+
// 原型定义防止数组和对象之间的转换
|
|
57
|
+
if (Object.prototype.toString.call(obj) === "[object Array]") {
|
|
58
|
+
myNewObj = []
|
|
59
|
+
} else {
|
|
60
|
+
myNewObj = {}
|
|
61
|
+
}
|
|
62
|
+
for (const i in obj) {
|
|
63
|
+
myNewObj[i] = this.clone(obj[i])
|
|
64
|
+
}
|
|
65
|
+
return myNewObj
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 去除字符串两端的空格
|
|
70
|
+
* @param str
|
|
71
|
+
* @return {string} 新的字符
|
|
72
|
+
*/
|
|
73
|
+
public trim(str: string): string {
|
|
74
|
+
return str.replace(/^\s+|\s+$/gm, "")
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 删除数组中某个值
|
|
79
|
+
* @param val string | 检索的对象
|
|
80
|
+
* @param arr Array | 查找数组
|
|
81
|
+
*/
|
|
82
|
+
public removeArray(val: string, arr: Array<any>) {
|
|
83
|
+
const index = arr.indexOf(val)
|
|
84
|
+
if (index > -1) {
|
|
85
|
+
arr.splice(index, 1)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 获取两个数组的交集
|
|
91
|
+
* @param a 数字数组
|
|
92
|
+
* @param b 数字数组
|
|
93
|
+
* @return {Array<Number>} 两个数组的交集数组
|
|
94
|
+
*/
|
|
95
|
+
public arrayIntersection(a: Array<number>, b: Array<number>): Array<number> {
|
|
96
|
+
let ai: number = 0,
|
|
97
|
+
bi: number = 0
|
|
98
|
+
const result: Array<number> = []
|
|
99
|
+
while (ai < a.length && bi < b.length) {
|
|
100
|
+
if (a[ai] < b[bi]) {
|
|
101
|
+
ai++
|
|
102
|
+
} else if (a[ai] > b[bi]) {
|
|
103
|
+
bi++
|
|
104
|
+
} /* they're equal */ else {
|
|
105
|
+
result.push(a[ai])
|
|
106
|
+
ai++
|
|
107
|
+
bi++
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 获取数组中最大的数字
|
|
115
|
+
* @param arr 数字数组
|
|
116
|
+
* @return {number} 最大值
|
|
117
|
+
*/
|
|
118
|
+
public getNumMax(arr: Array<number>): number {
|
|
119
|
+
let max: any
|
|
120
|
+
arr.forEach((v: number) => {
|
|
121
|
+
if (max) {
|
|
122
|
+
max = max > v ? max : v
|
|
123
|
+
} else {
|
|
124
|
+
max = v
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
return max
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* 获取数组中最小的数字
|
|
132
|
+
* @param arr 数字数组
|
|
133
|
+
* @return {number} 最小值
|
|
134
|
+
*/
|
|
135
|
+
public getNumMin(arr: Array<number>): number {
|
|
136
|
+
let min: any
|
|
137
|
+
arr.forEach((v: number) => {
|
|
138
|
+
if (min) {
|
|
139
|
+
min = min < v ? min : v
|
|
140
|
+
} else {
|
|
141
|
+
min = v
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
return min
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 将list转换为tree结构的数据
|
|
149
|
+
* @param list Array | 被转换的二维树结构数据
|
|
150
|
+
* @param pk string | 原始数据pk default:`_id`
|
|
151
|
+
* @param pIdfieldName string | 原始数据的 pId 字段名称 | default:`pId`
|
|
152
|
+
* @param childfieldName string | 原始数据的 child 字段名称 | default:`child`
|
|
153
|
+
* @param root {any} string | 根id | default:`null`
|
|
154
|
+
* @return {Array} Array | 树形结构数据
|
|
155
|
+
*/
|
|
156
|
+
public listToTree(
|
|
157
|
+
list: Array<any>,
|
|
158
|
+
pk?: string,
|
|
159
|
+
pIdfieldName?: string,
|
|
160
|
+
childfieldName?: string,
|
|
161
|
+
root?: any
|
|
162
|
+
): Array<any> {
|
|
163
|
+
// 创建Tree
|
|
164
|
+
pk = pk || "_id"
|
|
165
|
+
pIdfieldName = pIdfieldName || "pId"
|
|
166
|
+
childfieldName = childfieldName || "child"
|
|
167
|
+
root = typeof root === "undefined" ? null : root
|
|
168
|
+
const tree: Array<any> = []
|
|
169
|
+
if (Array.isArray(list)) {
|
|
170
|
+
// 创建基于主键的数组引用
|
|
171
|
+
const refer: any = {}
|
|
172
|
+
for (const key in list) {
|
|
173
|
+
const data: any = list[key]
|
|
174
|
+
refer[data[pk]] = list[key]
|
|
175
|
+
}
|
|
176
|
+
for (const key in list) {
|
|
177
|
+
const data = list[key]
|
|
178
|
+
const parentId = data[pIdfieldName]
|
|
179
|
+
if (root === parentId) {
|
|
180
|
+
tree.push(data)
|
|
181
|
+
} else {
|
|
182
|
+
if (typeof refer[parentId] !== "undefined") {
|
|
183
|
+
if (typeof refer[parentId][childfieldName] === "undefined") {
|
|
184
|
+
refer[parentId][childfieldName] = []
|
|
185
|
+
}
|
|
186
|
+
refer[parentId][childfieldName].push(data)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return tree
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 对象转数组
|
|
196
|
+
* @param obj
|
|
197
|
+
* @return {Array} 转换后的数组
|
|
198
|
+
*/
|
|
199
|
+
public objToArr(obj: any): Array<any> {
|
|
200
|
+
const arr: Array<any> = []
|
|
201
|
+
for (const key in obj) {
|
|
202
|
+
arr.push(obj[key])
|
|
203
|
+
}
|
|
204
|
+
return arr
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 对象属性替换
|
|
209
|
+
* @param data 原始对象
|
|
210
|
+
* @param options 替换项
|
|
211
|
+
* @param match 被查看替换的值 或正则表达式
|
|
212
|
+
* @param newVal 替换后的值 或 处理方法
|
|
213
|
+
* @return {*} 新对象
|
|
214
|
+
*/
|
|
215
|
+
public attReplace<T>(
|
|
216
|
+
data: T,
|
|
217
|
+
options: Array<string>,
|
|
218
|
+
match: RegExp | string,
|
|
219
|
+
newVal: string | any
|
|
220
|
+
): T {
|
|
221
|
+
const newData: any = this.clone(data)
|
|
222
|
+
options.forEach((key: any) => {
|
|
223
|
+
if (typeof newData[key] !== "undefined") {
|
|
224
|
+
if (
|
|
225
|
+
(match instanceof RegExp && match.test(newData[key])) ||
|
|
226
|
+
newData[key] === match
|
|
227
|
+
) {
|
|
228
|
+
if (typeof newVal === "function") {
|
|
229
|
+
newData[key] = newVal(newData[key])
|
|
230
|
+
} else {
|
|
231
|
+
newData[key] = newVal
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
return newData
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 判断是否为空
|
|
241
|
+
* @param object
|
|
242
|
+
* @return {boolean} true/false
|
|
243
|
+
*/
|
|
244
|
+
public isEmpty(object: any): boolean {
|
|
245
|
+
if (
|
|
246
|
+
object === "" ||
|
|
247
|
+
object === null ||
|
|
248
|
+
object === undefined ||
|
|
249
|
+
(typeof object === "object" && JSON.stringify(object) === "{}") ||
|
|
250
|
+
(Array.isArray(object) && object.length === 0)
|
|
251
|
+
) {
|
|
252
|
+
return true
|
|
253
|
+
}
|
|
254
|
+
return false
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* 格式化金额
|
|
259
|
+
*/
|
|
260
|
+
toMoney(num: any) {
|
|
261
|
+
if (num === 0) return "0.00"
|
|
262
|
+
if (this.isEmpty(num)) return "0.00"
|
|
263
|
+
num = num * 1
|
|
264
|
+
num = num.toFixed(2)
|
|
265
|
+
return num
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 日期格式化
|
|
270
|
+
* @param fmt 如:YYYY-mm-dd HH:MM表示2019-06-06 19:45
|
|
271
|
+
* @param date
|
|
272
|
+
* @param completion //是否补全 如 06, 如果设置为false 则返回 6
|
|
273
|
+
*/
|
|
274
|
+
dateFormat(fmt: string, date: Date, completion = true) {
|
|
275
|
+
let ret
|
|
276
|
+
const opt: any = {
|
|
277
|
+
"Y+": date.getFullYear().toString(), // 年
|
|
278
|
+
"m+": (date.getMonth() + 1).toString(), // 月
|
|
279
|
+
"d+": date.getDate().toString(), // 日
|
|
280
|
+
"H+": date.getHours().toString(), // 时
|
|
281
|
+
"M+": date.getMinutes().toString(), // 分
|
|
282
|
+
"S+": date.getSeconds().toString() // 秒
|
|
283
|
+
// 有其他格式化字符需求可以继续添加,必须转化成字符串
|
|
284
|
+
}
|
|
285
|
+
for (const k in opt) {
|
|
286
|
+
ret = new RegExp("(" + k + ")").exec(fmt)
|
|
287
|
+
if (ret) {
|
|
288
|
+
fmt = fmt.replace(
|
|
289
|
+
ret[1],
|
|
290
|
+
ret[1].length === 1
|
|
291
|
+
? opt[k]
|
|
292
|
+
: completion
|
|
293
|
+
? opt[k].padStart(ret[1].length, "0")
|
|
294
|
+
: opt[k]
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return fmt
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 数字补全
|
|
303
|
+
* @param num 输入的数字
|
|
304
|
+
* @param n 补全位数
|
|
305
|
+
* @param prefix 补全字符
|
|
306
|
+
*/
|
|
307
|
+
prefixInteger(num: number, n: number, prefix = "0") {
|
|
308
|
+
return (Array(n).join(prefix) + num).slice(-n)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* 下划线转换驼峰
|
|
313
|
+
* @param name
|
|
314
|
+
*/
|
|
315
|
+
toHump(name: string) {
|
|
316
|
+
return name.replace(/\_(\w)/g, function (all: any, letter) {
|
|
317
|
+
all
|
|
318
|
+
return letter.toUpperCase()
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* 驼峰转换下划线
|
|
323
|
+
* @param name
|
|
324
|
+
*/
|
|
325
|
+
toLine(name: string) {
|
|
326
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase()
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* 通过字节截取字符串
|
|
331
|
+
* @param {*} str 字符串
|
|
332
|
+
* @param {*} len 长度
|
|
333
|
+
*/
|
|
334
|
+
reBytesStr(str: string, len: number) {
|
|
335
|
+
if (typeof str !== "string") {
|
|
336
|
+
return ""
|
|
337
|
+
}
|
|
338
|
+
let num = 0
|
|
339
|
+
const str1 = str
|
|
340
|
+
for (let i = 0, lens = str1.length; i < lens; i++) {
|
|
341
|
+
num += str1.charCodeAt(i) > 255 ? 2 : 1
|
|
342
|
+
if (num > len) {
|
|
343
|
+
break
|
|
344
|
+
} else {
|
|
345
|
+
str = str1.substring(0, i + 1)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return str
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* 生成随机字符串
|
|
353
|
+
* @param len
|
|
354
|
+
*/
|
|
355
|
+
randomString(len: number = 32) {
|
|
356
|
+
const $chars = "ABCDEFGHJKMNPQRSTWXYZ0123456789"
|
|
357
|
+
const maxPos = $chars.length
|
|
358
|
+
let pwd = ""
|
|
359
|
+
for (let i = 0; i < len; i++) {
|
|
360
|
+
pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
|
|
361
|
+
}
|
|
362
|
+
return pwd
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* 返回固定位数随机数
|
|
367
|
+
* @param n
|
|
368
|
+
*/
|
|
369
|
+
randomNum(n: number = 5) {
|
|
370
|
+
let t = ""
|
|
371
|
+
for (let i = 0; i < n; i++) {
|
|
372
|
+
t += Math.floor(Math.random() * 10)
|
|
373
|
+
}
|
|
374
|
+
return t
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* 返回规定位数随机字符串
|
|
379
|
+
* @param len
|
|
380
|
+
* @param charSet
|
|
381
|
+
*/
|
|
382
|
+
randomStr(
|
|
383
|
+
len: number,
|
|
384
|
+
charSet: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
385
|
+
) {
|
|
386
|
+
let randomStr = ""
|
|
387
|
+
for (let i = 0; i < len; i++) {
|
|
388
|
+
randomStr += charSet.charAt(Math.floor(Math.random() * charSet.length))
|
|
389
|
+
}
|
|
390
|
+
return randomStr
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* 生成订单编号
|
|
395
|
+
* @param head 头部字符串
|
|
396
|
+
* @param tailLength 尾部随机数长度
|
|
397
|
+
* @param fmt 时间格式字符串
|
|
398
|
+
*/
|
|
399
|
+
numbering(head: string = "", tailLength = 5, fmt: string = "YYYYmmddHHMMSS") {
|
|
400
|
+
return head + this.dateFormat(fmt, new Date()) + this.randomNum(tailLength)
|
|
401
|
+
}
|
|
402
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"removeComments": true,
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"target": "es2017",
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"outDir": "./dist",
|
|
12
|
+
"baseUrl": "./",
|
|
13
|
+
"incremental": true,
|
|
14
|
+
"skipLibCheck": true
|
|
15
|
+
},
|
|
16
|
+
"exclude": [
|
|
17
|
+
"node_modules",
|
|
18
|
+
"dist",
|
|
19
|
+
]
|
|
20
|
+
}
|
package/view/api.ejs
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ApiCall, MoMethod } from '@/lib/apiv2/base'
|
|
2
|
+
import {
|
|
3
|
+
<% schemaKeys.forEach((key) => { %>
|
|
4
|
+
<%= key %>,
|
|
5
|
+
<% })%>
|
|
6
|
+
ObjectId,
|
|
7
|
+
int,
|
|
8
|
+
char,
|
|
9
|
+
varchar,
|
|
10
|
+
json,
|
|
11
|
+
datetime
|
|
12
|
+
} from './schemas'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
<% list.forEach((item) => { %>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* <%= item.tag %>|<%= item.summary %>
|
|
19
|
+
*/
|
|
20
|
+
export class <%= item.operationId %> extends ApiCall<<%= item.reqType %>,<%= item.resType %>> {
|
|
21
|
+
path = '<%= item.path%>'
|
|
22
|
+
method :MoMethod= '<%= item.method %>'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
<% })%>
|
package/view/schemas.ejs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ObjectId = string
|
|
2
|
+
export type int = number
|
|
3
|
+
export type char = string
|
|
4
|
+
export type varchar = string
|
|
5
|
+
export type json = {[key:string]:any}
|
|
6
|
+
export type datetime = Date | string
|
|
7
|
+
|
|
8
|
+
<% list.forEach((item) => { %>
|
|
9
|
+
export type <%= item.key %> = {
|
|
10
|
+
<% item.arr.forEach((item1) => { %> <%- item1 %> <% })%>
|
|
11
|
+
}
|
|
12
|
+
<% })%>
|