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.
Files changed (121) hide show
  1. package/.qoder/skills/midway-fatcms/01-quick-start.md +231 -0
  2. package/.qoder/skills/midway-fatcms/02-crud-quick.md +337 -0
  3. package/.qoder/skills/midway-fatcms/03-crud-sharding.md +488 -0
  4. package/.qoder/skills/midway-fatcms/04-condition-operators.md +93 -0
  5. package/.qoder/skills/midway-fatcms/05-configuration.md +290 -0
  6. package/.qoder/skills/midway-fatcms/06-builtin-functions.md +241 -0
  7. package/.qoder/skills/midway-fatcms/07-examples.md +500 -0
  8. package/.qoder/skills/midway-fatcms/SKILL.md +96 -0
  9. package/README.md +9 -9
  10. package/dist/controller/base/BaseApiController.d.ts +1 -2
  11. package/dist/controller/base/BaseApiController.js +0 -4
  12. package/dist/controller/gateway/DocGatewayController.js +1 -1
  13. package/dist/controller/manage/FlowConfigManageApi.js +4 -2
  14. package/dist/controller/manage/SysConfigMangeApi.js +6 -1
  15. package/dist/controller/manage/UserAccountManageApi.js +7 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +2 -2
  18. package/dist/libs/crud-pro/CrudPro.d.ts +23 -2
  19. package/dist/libs/crud-pro/CrudPro.js +53 -2
  20. package/dist/libs/crud-pro/interfaces.d.ts +82 -12
  21. package/dist/libs/crud-pro/models/CrudResult.d.ts +115 -0
  22. package/dist/libs/crud-pro/models/CrudResult.js +126 -0
  23. package/dist/libs/crud-pro/models/RequestModel.d.ts +2 -38
  24. package/dist/libs/crud-pro/models/RequestModel.js +2 -99
  25. package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +36 -2
  26. package/dist/libs/crud-pro/services/CrudProGenSqlCondition.js +8 -4
  27. package/dist/libs/crud-pro/services/CrudProTableMetaService.js +1 -2
  28. package/dist/libs/crud-pro/utils/OrderByUtils.d.ts +70 -0
  29. package/dist/libs/crud-pro/utils/OrderByUtils.js +158 -0
  30. package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +295 -0
  31. package/dist/libs/crud-pro-quick/CrudProQuick.js +529 -0
  32. package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +30 -0
  33. package/dist/{service/curd → libs/crud-pro-quick}/fixSoftDelete.js +3 -6
  34. package/dist/libs/crud-pro-quick/index.d.ts +36 -0
  35. package/dist/libs/crud-pro-quick/index.js +49 -0
  36. package/dist/libs/crud-pro-quick/models.d.ts +33 -0
  37. package/dist/libs/crud-pro-quick/models.js +2 -0
  38. package/dist/libs/crud-sharding/ShardingConfig.d.ts +15 -2
  39. package/dist/libs/crud-sharding/ShardingConfig.js +2 -2
  40. package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +119 -274
  41. package/dist/libs/crud-sharding/ShardingCrudPro.js +559 -379
  42. package/dist/libs/crud-sharding/ShardingMerger.d.ts +12 -20
  43. package/dist/libs/crud-sharding/ShardingMerger.js +36 -51
  44. package/dist/libs/crud-sharding/ShardingResult.d.ts +33 -0
  45. package/dist/libs/crud-sharding/ShardingResult.js +16 -0
  46. package/dist/libs/crud-sharding/ShardingRouter.d.ts +1 -0
  47. package/dist/libs/crud-sharding/ShardingRouter.js +25 -6
  48. package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +21 -4
  49. package/dist/libs/crud-sharding/ShardingTableCreator.js +193 -59
  50. package/dist/libs/crud-sharding/ShardingUtils.d.ts +48 -0
  51. package/dist/libs/crud-sharding/ShardingUtils.js +122 -1
  52. package/dist/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
  53. package/dist/libs/crud-sharding/index.d.ts +4 -3
  54. package/dist/libs/crud-sharding/index.js +14 -2
  55. package/dist/models/bizmodels.d.ts +2 -6
  56. package/dist/service/SysAppService.d.ts +2 -2
  57. package/dist/service/SysAppService.js +16 -5
  58. package/dist/service/SysConfigService.d.ts +1 -1
  59. package/dist/service/SysConfigService.js +7 -2
  60. package/dist/service/SysDictDataService.js +14 -4
  61. package/dist/service/SysMenuService.js +7 -2
  62. package/dist/service/curd/CurdMixService.d.ts +6 -4
  63. package/dist/service/curd/CurdMixService.js +16 -2
  64. package/dist/service/curd/CurdProService.d.ts +43 -27
  65. package/dist/service/curd/CurdProService.js +32 -33
  66. package/dist/service/flow/FlowConfigService.js +7 -2
  67. package/dist/service/flow/FlowInstanceCrudService.js +22 -19
  68. package/package.json +2 -1
  69. package/src/controller/base/BaseApiController.ts +0 -5
  70. package/src/controller/gateway/DocGatewayController.ts +1 -1
  71. package/src/controller/manage/CrudStandardDesignApi.ts +4 -3
  72. package/src/controller/manage/FlowConfigManageApi.ts +4 -2
  73. package/src/controller/manage/SysConfigMangeApi.ts +6 -1
  74. package/src/controller/manage/UserAccountManageApi.ts +7 -2
  75. package/src/index.ts +2 -2
  76. package/src/libs/crud-pro/CrudPro.ts +62 -4
  77. package/src/libs/crud-pro/interfaces.ts +110 -15
  78. package/src/libs/crud-pro/models/CrudResult.ts +178 -0
  79. package/src/libs/crud-pro/models/RequestModel.ts +4 -110
  80. package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +41 -2
  81. package/src/libs/crud-pro/services/CrudProGenSqlCondition.ts +11 -7
  82. package/src/libs/crud-pro/services/CrudProTableMetaService.ts +1 -2
  83. package/src/libs/crud-pro/utils/OrderByUtils.ts +169 -0
  84. package/src/libs/crud-pro-quick/CrudProQuick.ts +594 -0
  85. package/src/{service/curd → libs/crud-pro-quick}/fixSoftDelete.ts +23 -13
  86. package/src/libs/crud-pro-quick/index.ts +52 -0
  87. package/src/libs/crud-pro-quick/models.ts +35 -0
  88. package/src/libs/crud-sharding/ShardingConfig.ts +18 -2
  89. package/src/libs/crud-sharding/ShardingCrudPro.ts +689 -440
  90. package/src/libs/crud-sharding/ShardingMerger.ts +47 -73
  91. package/src/libs/crud-sharding/ShardingResult.ts +29 -0
  92. package/src/libs/crud-sharding/ShardingRouter.ts +27 -6
  93. package/src/libs/crud-sharding/ShardingTableCreator.ts +214 -71
  94. package/src/libs/crud-sharding/ShardingUtils.ts +137 -0
  95. package/src/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
  96. package/src/libs/crud-sharding/index.ts +14 -3
  97. package/src/models/bizmodels.ts +4 -7
  98. package/src/service/SysAppService.ts +18 -7
  99. package/src/service/SysConfigService.ts +8 -3
  100. package/src/service/SysDictDataService.ts +14 -4
  101. package/src/service/SysMenuService.ts +7 -2
  102. package/src/service/crudstd/CrudStdService.ts +2 -2
  103. package/src/service/curd/CurdMixService.ts +26 -5
  104. package/src/service/curd/CurdProService.ts +58 -39
  105. package/src/service/flow/FlowConfigService.ts +7 -2
  106. package/src/service/flow/FlowInstanceCrudService.ts +23 -20
  107. package/dist/libs/crud-pro/README.md +0 -809
  108. package/dist/libs/crud-pro/README_FUNC.md +0 -193
  109. package/dist/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
  110. package/dist/models/StandardColumns.d.ts +0 -71
  111. package/dist/models/StandardColumns.js +0 -28
  112. package/dist/service/curd/CrudProQuick.d.ts +0 -190
  113. package/dist/service/curd/CrudProQuick.js +0 -319
  114. package/dist/service/curd/README.md +0 -1001
  115. package/dist/service/curd/fixSoftDelete.d.ts +0 -20
  116. package/src/libs/crud-pro/README.md +0 -809
  117. package/src/libs/crud-pro/README_FUNC.md +0 -193
  118. package/src/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
  119. package/src/models/StandardColumns.ts +0 -76
  120. package/src/service/curd/CrudProQuick.ts +0 -360
  121. 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 countPromises = tables.map(table =>
68
- this.queryCountSafe(crudPro, table, reqJson, cfgJson)
69
- );
70
- const counts = await Promise.all(countPromises);
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
- const rows = await this.queryRowsSafeWithOffset(
85
- crudPro, target.table, reqJson, cfgJson,
86
- target.innerOffset, target.innerLimit
87
- );
88
- allRows = allRows.concat(rows);
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<any[]> {
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
- for (let i = 0; i < dataResults.length; i++) {
131
- allRows = allRows.concat(dataResults[i]);
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:所有表与条件取交集,最多取3张
246
+ // 未配置 recentTableCount:所有表与条件取交集,最多取默认数量
245
247
  const intersected = this.intersectWithCondition(shardingTables, config, condition);
246
- return intersected.slice(0, 3);
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 3;
482
+ return 2;
477
483
  case 'month':
478
- return 12;
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;