q-koa 11.8.0 → 11.8.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 +17 -3
- package/core/file/plugins/cache/config.js +7 -0
- package/core/file/plugins/cache/model.js +1 -1
- package/core/file/plugins/model/model.js +7 -0
- package/core/file/plugins/model/service.js +1 -0
- package/core/file/plugins/mp_user/config.js +8 -0
- package/core/file/plugins/mp_user/model.js +1 -1
- package/core/file/plugins/system/controller.js +94 -0
- package/core/file/plugins/system/service.js +14 -0
- package/package.json +1 -1
package/core/app.js
CHANGED
|
@@ -618,6 +618,11 @@ class APP {
|
|
|
618
618
|
...this.app[appName].attributes,
|
|
619
619
|
[folder]: _attributes,
|
|
620
620
|
}
|
|
621
|
+
const indexes = _.get(
|
|
622
|
+
this.app[appName].config[folder],
|
|
623
|
+
'indexList',
|
|
624
|
+
[]
|
|
625
|
+
)
|
|
621
626
|
|
|
622
627
|
const instance = this.app[appName].sequelize.define(
|
|
623
628
|
folder,
|
|
@@ -643,6 +648,11 @@ class APP {
|
|
|
643
648
|
}
|
|
644
649
|
},
|
|
645
650
|
},
|
|
651
|
+
...(indexes.length > 0
|
|
652
|
+
? {
|
|
653
|
+
indexes,
|
|
654
|
+
}
|
|
655
|
+
: {}),
|
|
646
656
|
}
|
|
647
657
|
)
|
|
648
658
|
instance.getName = function () {
|
|
@@ -675,9 +685,13 @@ class APP {
|
|
|
675
685
|
this.app[appName]
|
|
676
686
|
)
|
|
677
687
|
} else if (
|
|
678
|
-
[
|
|
679
|
-
|
|
680
|
-
|
|
688
|
+
[
|
|
689
|
+
'config',
|
|
690
|
+
'controller',
|
|
691
|
+
'validate',
|
|
692
|
+
'afterExecute',
|
|
693
|
+
'service',
|
|
694
|
+
].includes(n)
|
|
681
695
|
) {
|
|
682
696
|
const defaultPath = path.resolve(
|
|
683
697
|
__dirname,
|
|
@@ -203,6 +203,13 @@ exports.bulkCreateList = {
|
|
|
203
203
|
defaultValue: [],
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
exports.indexList = {
|
|
207
|
+
type: Sequelize.JSON,
|
|
208
|
+
comment: '索引',
|
|
209
|
+
allowNull: false,
|
|
210
|
+
defaultValue: [],
|
|
211
|
+
}
|
|
212
|
+
|
|
206
213
|
exports.alias = {
|
|
207
214
|
type: Sequelize.VIRTUAL,
|
|
208
215
|
comment: 'alias',
|
|
@@ -107,6 +107,7 @@ exports.loadModel = async ({ app, appName }) => {
|
|
|
107
107
|
editInline: config.editInline,
|
|
108
108
|
deleteCheckList: config.deleteCheckList,
|
|
109
109
|
bulkCreateList: config.bulkCreateList,
|
|
110
|
+
indexList: config.indexList,
|
|
110
111
|
list: attributes.map((attr, index) => {
|
|
111
112
|
const name = attr.match(/exports.(.*)=/)[1].trim()
|
|
112
113
|
let defaultValue = ''
|
|
@@ -11,6 +11,32 @@ const cache = new LRU({
|
|
|
11
11
|
maxAge: 1000 * 60 * 60,
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
+
const isSameArray = (_arr1 = [], _arr2 = [], deep = true) => {
|
|
15
|
+
const arr1 = Array.isArray(_arr1) ? _arr1 : [_arr1]
|
|
16
|
+
const arr2 = Array.isArray(_arr2) ? _arr2 : [_arr2]
|
|
17
|
+
return lodash.isEqualWith(
|
|
18
|
+
deep ? arr1 : arr1.sort(),
|
|
19
|
+
deep ? arr2 : arr2.sort(),
|
|
20
|
+
lodash.isEqual
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
const compareIndex = (tableIndexList, modelIndexList = [], model) => {
|
|
24
|
+
const flag =
|
|
25
|
+
tableIndexList
|
|
26
|
+
.filter((i) => i.name !== 'PRIMARY')
|
|
27
|
+
.filter((i) => {
|
|
28
|
+
return !(
|
|
29
|
+
((i.name.startsWith(model) &&
|
|
30
|
+
i.fields.every((f) => i.name.includes(f))) ||
|
|
31
|
+
modelIndexList.some((m) => m.name === i.name)) &&
|
|
32
|
+
modelIndexList.some((m) => isSameArray(m.fields, i.fields, true))
|
|
33
|
+
)
|
|
34
|
+
}).length === 0 &&
|
|
35
|
+
tableIndexList.filter((i) => i.name !== 'PRIMARY').length ===
|
|
36
|
+
modelIndexList.length
|
|
37
|
+
return flag
|
|
38
|
+
}
|
|
39
|
+
|
|
14
40
|
exports.initModel = async (ctx) => {
|
|
15
41
|
const { app, appName } = getAppByCtx(ctx)
|
|
16
42
|
const { model, option } = ctx.request.body
|
|
@@ -231,6 +257,8 @@ exports.showTables = async (ctx) => {
|
|
|
231
257
|
deleteCheckList: lodash.get(target, 'deleteCheckList', []),
|
|
232
258
|
// 批量更新字段
|
|
233
259
|
bulkCreateList: lodash.get(target, 'bulkCreateList', []),
|
|
260
|
+
// 索引
|
|
261
|
+
indexList: lodash.get(target, 'indexList', []),
|
|
234
262
|
|
|
235
263
|
fn: app.controller[_model] ? Object.keys(app.controller[_model]) : [],
|
|
236
264
|
}
|
|
@@ -672,3 +700,69 @@ exports.copyOther = async (ctx) => {
|
|
|
672
700
|
}
|
|
673
701
|
ctx.SUCCESS({ successList, failList })
|
|
674
702
|
}
|
|
703
|
+
|
|
704
|
+
exports.checkIndex = async (ctx) => {
|
|
705
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
706
|
+
|
|
707
|
+
const { model } = ctx.request.body
|
|
708
|
+
if (!model) return ctx.ERROR('model不能为空')
|
|
709
|
+
|
|
710
|
+
if (model === 'all') {
|
|
711
|
+
const modelList = Object.keys(app.model)
|
|
712
|
+
let res = {}
|
|
713
|
+
for (let i = 0; i < modelList.length; i++) {
|
|
714
|
+
const current = modelList[i]
|
|
715
|
+
try {
|
|
716
|
+
const tableIndexList = await app.service.system.getTableIndex({
|
|
717
|
+
app,
|
|
718
|
+
model: current,
|
|
719
|
+
})
|
|
720
|
+
const modelIndexList = app.config[current].indexList
|
|
721
|
+
|
|
722
|
+
const isSame = compareIndex(tableIndexList, modelIndexList, current)
|
|
723
|
+
if (isSame) {
|
|
724
|
+
} else {
|
|
725
|
+
res = {
|
|
726
|
+
...res,
|
|
727
|
+
[current]: {
|
|
728
|
+
isSame,
|
|
729
|
+
tableIndexList,
|
|
730
|
+
},
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
} catch (e) {
|
|
734
|
+
throw new Error(`${current}: ${e.message}`)
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return ctx.SUCCESS(res)
|
|
738
|
+
} else {
|
|
739
|
+
const tableIndexList = await app.service.system.getTableIndex({
|
|
740
|
+
app,
|
|
741
|
+
model,
|
|
742
|
+
})
|
|
743
|
+
|
|
744
|
+
const modelIndexList = app.config[model].indexList
|
|
745
|
+
|
|
746
|
+
const isSame = compareIndex(tableIndexList, modelIndexList, model)
|
|
747
|
+
return ctx.SUCCESS({
|
|
748
|
+
isSame,
|
|
749
|
+
...(isSame ? {} : { tableIndexList }),
|
|
750
|
+
})
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
exports.dropIndex = async (ctx) => {
|
|
755
|
+
const { app, appName } = getAppByCtx(ctx)
|
|
756
|
+
const { model, key } = ctx.request.body
|
|
757
|
+
|
|
758
|
+
if (!model) return ctx.ERROR(`drop model?`)
|
|
759
|
+
const keyList = Array.isArray(key) ? key : [key]
|
|
760
|
+
if (keyList.length === 0) return ctx.ERROR(`drop key?`)
|
|
761
|
+
|
|
762
|
+
const dropStr = keyList.map((item) => `DROP KEY \`${item}\``).join(',')
|
|
763
|
+
const result = await app.sequelize.query(
|
|
764
|
+
`ALTER TABLE \`${model}\` ${dropStr}`
|
|
765
|
+
)
|
|
766
|
+
|
|
767
|
+
ctx.SUCCESS(result)
|
|
768
|
+
}
|
|
@@ -327,3 +327,17 @@ exports.initData = async ({ includes, excludes, app, ctx }) => {
|
|
|
327
327
|
}
|
|
328
328
|
return obj
|
|
329
329
|
}
|
|
330
|
+
|
|
331
|
+
exports.getTableIndex = async ({ app, model }) => {
|
|
332
|
+
if (!model) throw new Error(`没有${model}`)
|
|
333
|
+
|
|
334
|
+
const res = await app.sequelize.query(`show keys from \`${model}\``)
|
|
335
|
+
const groupRes = lodash.groupBy(res[0], 'Key_name')
|
|
336
|
+
const result = Object.keys(groupRes).map((Key_name) => {
|
|
337
|
+
return {
|
|
338
|
+
name: groupRes[Key_name][0].Key_name,
|
|
339
|
+
fields: groupRes[Key_name].map((i) => i.Column_name),
|
|
340
|
+
}
|
|
341
|
+
})
|
|
342
|
+
return result
|
|
343
|
+
}
|