midway-fatcms 0.0.6 → 0.0.8
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/.qoder/skills/midway-fatcms/01-quick-start.md +231 -0
- package/.qoder/skills/midway-fatcms/02-crud-quick.md +337 -0
- package/.qoder/skills/midway-fatcms/03-crud-sharding.md +488 -0
- package/.qoder/skills/midway-fatcms/04-condition-operators.md +93 -0
- package/.qoder/skills/midway-fatcms/05-configuration.md +290 -0
- package/.qoder/skills/midway-fatcms/06-builtin-functions.md +241 -0
- package/.qoder/skills/midway-fatcms/07-examples.md +500 -0
- package/.qoder/skills/midway-fatcms/SKILL.md +96 -0
- package/README.md +9 -9
- package/dist/controller/base/BaseApiController.d.ts +1 -2
- package/dist/controller/base/BaseApiController.js +0 -4
- package/dist/controller/gateway/DocGatewayController.js +1 -1
- package/dist/controller/manage/FlowConfigManageApi.js +4 -2
- package/dist/controller/manage/SysConfigMangeApi.js +6 -1
- package/dist/controller/manage/UserAccountManageApi.js +7 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/libs/crud-pro/CrudPro.d.ts +23 -2
- package/dist/libs/crud-pro/CrudPro.js +53 -2
- package/dist/libs/crud-pro/interfaces.d.ts +82 -12
- package/dist/libs/crud-pro/models/CrudResult.d.ts +115 -0
- package/dist/libs/crud-pro/models/CrudResult.js +126 -0
- package/dist/libs/crud-pro/models/RequestModel.d.ts +2 -38
- package/dist/libs/crud-pro/models/RequestModel.js +2 -99
- package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +36 -2
- package/dist/libs/crud-pro/services/CrudProGenSqlCondition.js +8 -4
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +1 -2
- package/dist/libs/crud-pro/utils/OrderByUtils.d.ts +70 -0
- package/dist/libs/crud-pro/utils/OrderByUtils.js +158 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +295 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.js +529 -0
- package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +30 -0
- package/dist/{service/curd → libs/crud-pro-quick}/fixSoftDelete.js +3 -6
- package/dist/libs/crud-pro-quick/index.d.ts +36 -0
- package/dist/libs/crud-pro-quick/index.js +49 -0
- package/dist/libs/crud-pro-quick/models.d.ts +33 -0
- package/dist/libs/crud-pro-quick/models.js +2 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +15 -2
- package/dist/libs/crud-sharding/ShardingConfig.js +2 -2
- package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +119 -274
- package/dist/libs/crud-sharding/ShardingCrudPro.js +559 -379
- package/dist/libs/crud-sharding/ShardingMerger.d.ts +12 -20
- package/dist/libs/crud-sharding/ShardingMerger.js +36 -51
- package/dist/libs/crud-sharding/ShardingResult.d.ts +33 -0
- package/dist/libs/crud-sharding/ShardingResult.js +16 -0
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +1 -0
- package/dist/libs/crud-sharding/ShardingRouter.js +25 -6
- package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +21 -4
- package/dist/libs/crud-sharding/ShardingTableCreator.js +193 -59
- package/dist/libs/crud-sharding/ShardingUtils.d.ts +48 -0
- package/dist/libs/crud-sharding/ShardingUtils.js +122 -1
- package/dist/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/dist/libs/crud-sharding/index.d.ts +4 -3
- package/dist/libs/crud-sharding/index.js +14 -2
- package/dist/models/bizmodels.d.ts +2 -6
- package/dist/service/SysAppService.d.ts +2 -2
- package/dist/service/SysAppService.js +16 -5
- package/dist/service/SysConfigService.d.ts +1 -1
- package/dist/service/SysConfigService.js +7 -2
- package/dist/service/SysDictDataService.js +14 -4
- package/dist/service/SysMenuService.js +7 -2
- package/dist/service/curd/CurdMixService.d.ts +6 -4
- package/dist/service/curd/CurdMixService.js +16 -2
- package/dist/service/curd/CurdProService.d.ts +43 -27
- package/dist/service/curd/CurdProService.js +32 -33
- package/dist/service/flow/FlowConfigService.js +7 -2
- package/dist/service/flow/FlowInstanceCrudService.js +22 -19
- package/package.json +2 -1
- package/src/controller/base/BaseApiController.ts +0 -5
- package/src/controller/gateway/DocGatewayController.ts +1 -1
- package/src/controller/manage/CrudStandardDesignApi.ts +4 -3
- package/src/controller/manage/FlowConfigManageApi.ts +4 -2
- package/src/controller/manage/SysConfigMangeApi.ts +6 -1
- package/src/controller/manage/UserAccountManageApi.ts +7 -2
- package/src/index.ts +2 -2
- package/src/libs/crud-pro/CrudPro.ts +62 -4
- package/src/libs/crud-pro/interfaces.ts +110 -15
- package/src/libs/crud-pro/models/CrudResult.ts +178 -0
- package/src/libs/crud-pro/models/RequestModel.ts +4 -110
- package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +41 -2
- package/src/libs/crud-pro/services/CrudProGenSqlCondition.ts +11 -7
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +1 -2
- package/src/libs/crud-pro/utils/OrderByUtils.ts +169 -0
- package/src/libs/crud-pro-quick/CrudProQuick.ts +594 -0
- package/src/{service/curd → libs/crud-pro-quick}/fixSoftDelete.ts +23 -13
- package/src/libs/crud-pro-quick/index.ts +52 -0
- package/src/libs/crud-pro-quick/models.ts +35 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +18 -2
- package/src/libs/crud-sharding/ShardingCrudPro.ts +689 -440
- package/src/libs/crud-sharding/ShardingMerger.ts +47 -73
- package/src/libs/crud-sharding/ShardingResult.ts +29 -0
- package/src/libs/crud-sharding/ShardingRouter.ts +27 -6
- package/src/libs/crud-sharding/ShardingTableCreator.ts +214 -71
- package/src/libs/crud-sharding/ShardingUtils.ts +137 -0
- package/src/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/src/libs/crud-sharding/index.ts +14 -3
- package/src/models/bizmodels.ts +4 -7
- package/src/service/SysAppService.ts +18 -7
- package/src/service/SysConfigService.ts +8 -3
- package/src/service/SysDictDataService.ts +14 -4
- package/src/service/SysMenuService.ts +7 -2
- package/src/service/crudstd/CrudStdService.ts +2 -2
- package/src/service/curd/CurdMixService.ts +26 -5
- package/src/service/curd/CurdProService.ts +58 -39
- package/src/service/flow/FlowConfigService.ts +7 -2
- package/src/service/flow/FlowInstanceCrudService.ts +23 -20
- package/dist/libs/crud-pro/README.md +0 -809
- package/dist/libs/crud-pro/README_FUNC.md +0 -193
- package/dist/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/dist/models/StandardColumns.d.ts +0 -71
- package/dist/models/StandardColumns.js +0 -28
- package/dist/service/curd/CrudProQuick.d.ts +0 -190
- package/dist/service/curd/CrudProQuick.js +0 -319
- package/dist/service/curd/README.md +0 -1001
- package/dist/service/curd/fixSoftDelete.d.ts +0 -20
- package/src/libs/crud-pro/README.md +0 -809
- package/src/libs/crud-pro/README_FUNC.md +0 -193
- package/src/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/src/models/StandardColumns.ts +0 -76
- package/src/service/curd/CrudProQuick.ts +0 -360
- package/src/service/curd/README.md +0 -1001
|
@@ -10,6 +10,15 @@ import { ShardingCountCache, shardingHashCondition } from './ShardingCountCache'
|
|
|
10
10
|
export interface IShardingPageQueryResult {
|
|
11
11
|
rows: any[];
|
|
12
12
|
total_count: number;
|
|
13
|
+
lastCtx: ExecuteContext | null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 列表查询结果
|
|
18
|
+
*/
|
|
19
|
+
export interface IShardingListQueryResult {
|
|
20
|
+
rows: any[];
|
|
21
|
+
lastCtx: ExecuteContext | null;
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
/**
|
|
@@ -63,16 +72,17 @@ export class ShardingMerger {
|
|
|
63
72
|
const offset = (pageNo - 1) * pageSize;
|
|
64
73
|
const targetEnd = offset + pageSize; // 需要取到第几条
|
|
65
74
|
|
|
66
|
-
// 1.
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
// 1. 串行查询所有分表的记录数
|
|
76
|
+
const counts: number[] = [];
|
|
77
|
+
for (const table of tables) {
|
|
78
|
+
const count = await this.queryCountSafe(crudPro, table, reqJson, cfgJson);
|
|
79
|
+
counts.push(count);
|
|
80
|
+
}
|
|
71
81
|
const totalCount = counts.reduce((sum, c) => sum + c, 0);
|
|
72
82
|
|
|
73
83
|
// 总数为0,直接返回
|
|
74
84
|
if (totalCount === 0) {
|
|
75
|
-
return { rows: [], total_count: 0 };
|
|
85
|
+
return { rows: [], total_count: 0, lastCtx: null };
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
// 2. 根据累计数量直接定位目标表
|
|
@@ -80,17 +90,21 @@ export class ShardingMerger {
|
|
|
80
90
|
|
|
81
91
|
// 3. 只查询包含目标数据的分表
|
|
82
92
|
let allRows: any[] = [];
|
|
93
|
+
let lastCtx: ExecuteContext | null = null;
|
|
83
94
|
for (const target of targetTables) {
|
|
84
|
-
|
|
85
|
-
crudPro, target.table, reqJson, cfgJson,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
try {
|
|
96
|
+
const ctx = await this.executeQueryWithOffset(crudPro, target.table, reqJson, cfgJson, target.innerOffset, target.innerLimit);
|
|
97
|
+
lastCtx = ctx;
|
|
98
|
+
allRows = allRows.concat(ctx.getResRows() || []);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
// 表不存在或其他错误,跳过
|
|
101
|
+
}
|
|
89
102
|
}
|
|
90
103
|
|
|
91
104
|
return {
|
|
92
105
|
rows: allRows,
|
|
93
106
|
total_count: totalCount,
|
|
107
|
+
lastCtx,
|
|
94
108
|
};
|
|
95
109
|
}
|
|
96
110
|
|
|
@@ -102,8 +116,8 @@ export class ShardingMerger {
|
|
|
102
116
|
* - orderBy 为 timeColumn DESC 或 timeColumn ASC
|
|
103
117
|
*
|
|
104
118
|
* 执行流程:
|
|
105
|
-
* 1.
|
|
106
|
-
* 2.
|
|
119
|
+
* 1. 串行查询分表,按表顺序拼接
|
|
120
|
+
* 2. 达到 maxRows 上限后立即停止,避免查询无关表
|
|
107
121
|
*
|
|
108
122
|
* @param crudPro CrudPro 实例
|
|
109
123
|
* @param tables 分表列表(DESC: 新→旧,ASC: 旧→新)
|
|
@@ -118,25 +132,33 @@ export class ShardingMerger {
|
|
|
118
132
|
reqJson: IRequestModel,
|
|
119
133
|
cfgJson: IRequestCfgModel,
|
|
120
134
|
maxRows: number = 10000
|
|
121
|
-
): Promise<
|
|
122
|
-
//
|
|
123
|
-
const dataPromises = tables.map(table =>
|
|
124
|
-
this.queryRowsSafe(crudPro, table, reqJson, cfgJson, maxRows)
|
|
125
|
-
);
|
|
126
|
-
const dataResults = await Promise.all(dataPromises);
|
|
127
|
-
|
|
128
|
-
// 按表顺序拼接(表顺序即数据顺序,无需排序)
|
|
135
|
+
): Promise<IShardingListQueryResult> {
|
|
136
|
+
// 串行查询分表,按表顺序拼接,达到上限即停
|
|
129
137
|
let allRows: any[] = [];
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
let lastCtx: ExecuteContext | null = null;
|
|
139
|
+
|
|
140
|
+
for (const table of tables) {
|
|
141
|
+
const needMore = maxRows - allRows.length;
|
|
142
|
+
if (needMore <= 0) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const ctx = await this.executeQuery(crudPro, table, reqJson, cfgJson, needMore);
|
|
148
|
+
lastCtx = ctx;
|
|
149
|
+
allRows = allRows.concat(ctx.getResRows() || []);
|
|
150
|
+
} catch (e) {
|
|
151
|
+
// 表不存在或其他错误,跳过
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 达到上限后停止,不再查询后续表
|
|
133
155
|
if (allRows.length >= maxRows) {
|
|
134
156
|
allRows = allRows.slice(0, maxRows);
|
|
135
157
|
break;
|
|
136
158
|
}
|
|
137
159
|
}
|
|
138
160
|
|
|
139
|
-
return allRows;
|
|
161
|
+
return { rows: allRows, lastCtx };
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
// ============ 私有方法:分页定位 ============
|
|
@@ -254,54 +276,6 @@ export class ShardingMerger {
|
|
|
254
276
|
}
|
|
255
277
|
}
|
|
256
278
|
|
|
257
|
-
/**
|
|
258
|
-
* 安全查询数据行(表不存在时返回空数组)
|
|
259
|
-
*/
|
|
260
|
-
private async queryRowsSafe(
|
|
261
|
-
crudPro: CrudPro,
|
|
262
|
-
table: string,
|
|
263
|
-
reqJson: IRequestModel,
|
|
264
|
-
cfgJson: IRequestCfgModel,
|
|
265
|
-
limit?: number
|
|
266
|
-
): Promise<any[]> {
|
|
267
|
-
try {
|
|
268
|
-
const ctx = await this.executeQuery(crudPro, table, reqJson, cfgJson, limit);
|
|
269
|
-
return ctx.getResRows() || [];
|
|
270
|
-
} catch (e) {
|
|
271
|
-
// 表不存在或其他错误,返回空数组
|
|
272
|
-
return [];
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* 安全查询数据行(支持表内偏移,表不存在时返回空数组)
|
|
278
|
-
*
|
|
279
|
-
* 用于分页定位后,直接从某张表指定偏移处取数据
|
|
280
|
-
*
|
|
281
|
-
* @param crudPro CrudPro 实例
|
|
282
|
-
* @param table 分表名
|
|
283
|
-
* @param reqJson 请求参数
|
|
284
|
-
* @param cfgJson 配置
|
|
285
|
-
* @param innerOffset 表内偏移(跳过前 N 条)
|
|
286
|
-
* @param innerLimit 取多少条
|
|
287
|
-
*/
|
|
288
|
-
private async queryRowsSafeWithOffset(
|
|
289
|
-
crudPro: CrudPro,
|
|
290
|
-
table: string,
|
|
291
|
-
reqJson: IRequestModel,
|
|
292
|
-
cfgJson: IRequestCfgModel,
|
|
293
|
-
innerOffset: number,
|
|
294
|
-
innerLimit: number
|
|
295
|
-
): Promise<any[]> {
|
|
296
|
-
try {
|
|
297
|
-
const ctx = await this.executeQueryWithOffset(crudPro, table, reqJson, cfgJson, innerOffset, innerLimit);
|
|
298
|
-
return ctx.getResRows() || [];
|
|
299
|
-
} catch (e) {
|
|
300
|
-
// 表不存在或其他错误,返回空数组
|
|
301
|
-
return [];
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
279
|
/**
|
|
306
280
|
* 执行 COUNT 查询
|
|
307
281
|
*/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ExecuteContext } from '@/libs/crud-pro/models/ExecuteContext';
|
|
2
|
+
import { CrudResultBase } from '@/libs/crud-pro/models/CrudResult';
|
|
3
|
+
|
|
4
|
+
/** 分表批量插入结果 */
|
|
5
|
+
class ShardingBatchInsertResult extends CrudResultBase {
|
|
6
|
+
readonly totalAffected: number;
|
|
7
|
+
readonly tableResults: Array<{ table: string; affected: number; rowCount: number }>;
|
|
8
|
+
readonly tableCount: number;
|
|
9
|
+
readonly success: boolean;
|
|
10
|
+
readonly errors: Array<{ table: string; error: Error }>;
|
|
11
|
+
|
|
12
|
+
constructor(data: {
|
|
13
|
+
totalAffected: number;
|
|
14
|
+
tableResults: Array<{ table: string; affected: number; rowCount: number }>;
|
|
15
|
+
tableCount: number;
|
|
16
|
+
success: boolean;
|
|
17
|
+
errors: Array<{ table: string; error: Error }>;
|
|
18
|
+
lastContext: ExecuteContext;
|
|
19
|
+
}) {
|
|
20
|
+
super(data.lastContext);
|
|
21
|
+
this.totalAffected = data.totalAffected;
|
|
22
|
+
this.tableResults = data.tableResults;
|
|
23
|
+
this.tableCount = data.tableCount;
|
|
24
|
+
this.success = data.success;
|
|
25
|
+
this.errors = data.errors;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { ShardingBatchInsertResult };
|
|
@@ -166,6 +166,8 @@ export class ShardingRouter {
|
|
|
166
166
|
return this.formatTableName(baseTable, suffix, config);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
// 时间分表写操作必须包含时间字段
|
|
170
|
+
// 但查询操作允许回退到 recentTableCount
|
|
169
171
|
const recentCount = this.getRecentCountByGranularity(granularity, config);
|
|
170
172
|
return this.getRecentTables(baseTable, granularity, recentCount, config);
|
|
171
173
|
}
|
|
@@ -241,9 +243,10 @@ export class ShardingRouter {
|
|
|
241
243
|
return this.intersectWithCondition(recentTables, config, condition);
|
|
242
244
|
}
|
|
243
245
|
|
|
244
|
-
// 未配置 recentTableCount
|
|
246
|
+
// 未配置 recentTableCount:所有表与条件取交集,最多取默认数量
|
|
245
247
|
const intersected = this.intersectWithCondition(shardingTables, config, condition);
|
|
246
|
-
|
|
248
|
+
const defaultCount = this.getDefaultRecentCount(config);
|
|
249
|
+
return intersected.slice(0, defaultCount);
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
private intersectWithCondition(
|
|
@@ -268,6 +271,7 @@ export class ShardingRouter {
|
|
|
268
271
|
return tables.includes(targetTable) ? [targetTable] : [];
|
|
269
272
|
}
|
|
270
273
|
|
|
274
|
+
// condition 存在但不包含时间字段,返回所有表(按时间降序)
|
|
271
275
|
return this.sortTablesByTimeDesc(tables);
|
|
272
276
|
}
|
|
273
277
|
|
|
@@ -437,6 +441,8 @@ export class ShardingRouter {
|
|
|
437
441
|
return tables;
|
|
438
442
|
}
|
|
439
443
|
|
|
444
|
+
// ============ 格式化 ============
|
|
445
|
+
|
|
440
446
|
private getRecentTables(
|
|
441
447
|
baseTable: string,
|
|
442
448
|
granularity: ShardingTimeGranularity,
|
|
@@ -473,15 +479,30 @@ export class ShardingRouter {
|
|
|
473
479
|
|
|
474
480
|
switch (granularity) {
|
|
475
481
|
case 'year':
|
|
476
|
-
return
|
|
482
|
+
return 2;
|
|
477
483
|
case 'month':
|
|
478
|
-
return
|
|
484
|
+
return 3;
|
|
479
485
|
case 'day':
|
|
480
486
|
return 7;
|
|
481
487
|
}
|
|
482
488
|
}
|
|
483
489
|
|
|
484
|
-
|
|
490
|
+
private getDefaultRecentCount(config: IShardingConfig): number {
|
|
491
|
+
if (config.recentTableCount !== undefined && config.recentTableCount > 0) {
|
|
492
|
+
return config.recentTableCount;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
switch (config.type) {
|
|
496
|
+
case ShardingType.YEAR:
|
|
497
|
+
return 2;
|
|
498
|
+
case ShardingType.MONTH:
|
|
499
|
+
return 3;
|
|
500
|
+
case ShardingType.DAY:
|
|
501
|
+
return 7;
|
|
502
|
+
default:
|
|
503
|
+
return 3;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
485
506
|
|
|
486
507
|
private calculateRangeIndex(value: any, count: number): number {
|
|
487
508
|
if (typeof value === 'number') {
|
|
@@ -503,7 +524,7 @@ export class ShardingRouter {
|
|
|
503
524
|
return hash;
|
|
504
525
|
}
|
|
505
526
|
|
|
506
|
-
// ============
|
|
527
|
+
// ============ 表名格式化 ============
|
|
507
528
|
|
|
508
529
|
private formatTableName(baseTable: string, suffix: string, config: IShardingConfig): string {
|
|
509
530
|
const formattedSuffix = config.suffixFormatter ? config.suffixFormatter(suffix) : suffix;
|