midway-fatcms 0.0.7 → 0.0.9
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 +375 -0
- package/.qoder/skills/midway-fatcms/03-crud-sharding.md +489 -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 +504 -0
- package/.qoder/skills/midway-fatcms/SKILL.md +96 -0
- package/README.md +9 -9
- package/dist/configuration.d.ts +10 -0
- package/dist/configuration.js +26 -0
- 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/helpers.controller.d.ts +6 -0
- package/dist/controller/helpers.controller.js +19 -0
- 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 +51 -3
- package/dist/libs/crud-pro/CrudPro.js +111 -4
- package/dist/libs/crud-pro/exceptions.d.ts +7 -0
- package/dist/libs/crud-pro/exceptions.js +7 -0
- package/dist/libs/crud-pro/interfaces.d.ts +83 -12
- package/dist/libs/crud-pro/models/CrudResult.d.ts +116 -0
- package/dist/libs/crud-pro/models/CrudResult.js +126 -0
- package/dist/libs/crud-pro/models/RequestModel.d.ts +2 -2
- package/dist/libs/crud-pro/models/ServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +70 -2
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +205 -13
- 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.d.ts +36 -0
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +97 -4
- package/dist/libs/crud-pro/services/CurdProServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CurdProServiceHub.js +6 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +382 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.js +689 -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/ShardingBase.d.ts +78 -0
- package/dist/libs/crud-sharding/ShardingBase.js +179 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.d.ts +35 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.js +297 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.d.ts +38 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.js +86 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.d.ts +39 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.js +74 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.d.ts +66 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.js +524 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +25 -10
- package/dist/libs/crud-sharding/ShardingConfig.js +5 -5
- package/dist/libs/crud-sharding/ShardingMerger.d.ts +10 -18
- package/dist/libs/crud-sharding/ShardingMerger.js +27 -44
- package/dist/libs/crud-sharding/ShardingResult.d.ts +33 -0
- package/dist/libs/crud-sharding/ShardingResult.js +16 -0
- 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 +13 -15
- package/dist/libs/crud-sharding/index.js +33 -17
- package/dist/models/RedisKeys.d.ts +1 -0
- package/dist/models/RedisKeys.js +1 -0
- 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/TableMetaCacheRedisSubscriber.d.ts +31 -0
- package/dist/service/TableMetaCacheRedisSubscriber.js +98 -0
- package/dist/service/curd/CurdMixService.d.ts +6 -4
- package/dist/service/curd/CurdMixService.js +16 -2
- package/dist/service/curd/CurdProService.d.ts +149 -29
- package/dist/service/curd/CurdProService.js +157 -38
- package/dist/service/flow/FlowConfigService.js +7 -2
- package/dist/service/flow/FlowInstanceCrudService.js +22 -19
- package/package.json +1 -1
- package/src/configuration.ts +27 -0
- package/src/controller/base/BaseApiController.ts +0 -5
- package/src/controller/gateway/DocGatewayController.ts +1 -1
- package/src/controller/helpers.controller.ts +15 -0
- 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 +134 -7
- package/src/libs/crud-pro/exceptions.ts +8 -0
- package/src/libs/crud-pro/interfaces.ts +111 -15
- package/src/libs/crud-pro/models/CrudResult.ts +178 -0
- package/src/libs/crud-pro/models/RequestModel.ts +2 -2
- package/src/libs/crud-pro/models/ServiceHub.ts +4 -0
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +238 -15
- 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 +110 -3
- package/src/libs/crud-pro/services/CurdProServiceHub.ts +8 -0
- package/src/libs/crud-pro-quick/CrudProQuick.ts +782 -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/ShardingBase.ts +256 -0
- package/src/libs/crud-sharding/ShardingByCustomCrud.ts +329 -0
- package/src/libs/crud-sharding/ShardingByHashCrud.ts +111 -0
- package/src/libs/crud-sharding/ShardingByKeyCrud.ts +97 -0
- package/src/libs/crud-sharding/ShardingByTimeCrud.ts +628 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +28 -10
- package/src/libs/crud-sharding/ShardingMerger.ts +35 -63
- package/src/libs/crud-sharding/ShardingResult.ts +29 -0
- 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 +30 -16
- package/src/models/RedisKeys.ts +1 -0
- 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/TableMetaCacheRedisSubscriber.ts +105 -0
- package/src/service/crudstd/CrudStdService.ts +2 -2
- package/src/service/curd/CurdMixService.ts +26 -5
- package/src/service/curd/CurdProService.ts +186 -45
- package/src/service/flow/FlowConfigService.ts +7 -2
- package/src/service/flow/FlowInstanceCrudService.ts +23 -20
- package/.qoder/skills/midway-fatcms-crud/SKILL.md +0 -375
- package/.qoder/skills/midway-fatcms-crud/examples.md +0 -990
- package/.qoder/skills/midway-fatcms-crud/reference.md +0 -568
- 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/libs/crud-sharding/ShardingCrudPro.d.ts +0 -363
- package/dist/libs/crud-sharding/ShardingCrudPro.js +0 -675
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +0 -69
- package/dist/libs/crud-sharding/ShardingRouter.js +0 -377
- 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 -1100
- 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/libs/crud-sharding/ShardingCrudPro.ts +0 -835
- package/src/libs/crud-sharding/ShardingRouter.ts +0 -512
- package/src/models/StandardColumns.ts +0 -76
- package/src/service/curd/CrudProQuick.ts +0 -360
- package/src/service/curd/README.md +0 -1100
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { IRequestModel } from '@/libs/crud-pro/interfaces';
|
|
2
|
+
import { ExecuteContext } from '@/libs/crud-pro/models/ExecuteContext';
|
|
3
|
+
import { KeysOfSimpleSQL } from '@/libs/crud-pro/models/keys';
|
|
4
|
+
import { IShardingConfig, IShardingRouterContext, CrudProFactory } from './ShardingConfig';
|
|
5
|
+
import { ShardingBase } from './ShardingBase';
|
|
6
|
+
import {
|
|
7
|
+
CrudWriteResult,
|
|
8
|
+
CrudQueryOneResult,
|
|
9
|
+
CrudQueryListResult,
|
|
10
|
+
CrudQueryPageResult,
|
|
11
|
+
CrudExistResult,
|
|
12
|
+
CrudCountResult,
|
|
13
|
+
CrudUpsertResult,
|
|
14
|
+
} from '@/libs/crud-pro/models/CrudResult';
|
|
15
|
+
import { ShardingBatchInsertResult } from './ShardingResult';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 自定义分表 CRUD
|
|
19
|
+
*
|
|
20
|
+
* 分表名称完全由用户提供的 customRouter 函数决定。
|
|
21
|
+
* 适用于无法用时间/哈希/键值覆盖的复杂场景(如原 RANGE 分表)。
|
|
22
|
+
*
|
|
23
|
+
* 特性:
|
|
24
|
+
* - 路由:customRouter({ config, data?, condition? }) → 表名或表名数组
|
|
25
|
+
* - 插入:customRouter 返回单个表名
|
|
26
|
+
* - 查询:customRouter 返回表名数组 → 过滤已存在表
|
|
27
|
+
* - insertOrUpdate:统一由 condition 路由定位分表,查找与插入在同一分表
|
|
28
|
+
*/
|
|
29
|
+
export class ShardingByCustomCrud extends ShardingBase {
|
|
30
|
+
|
|
31
|
+
constructor(crudProFactory: CrudProFactory, config: IShardingConfig) {
|
|
32
|
+
super(crudProFactory, config);
|
|
33
|
+
|
|
34
|
+
if (!config.customRouter) {
|
|
35
|
+
throw new Error('[ShardingByCustomCrud] 自定义分表必须提供 customRouter 函数');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============ 路由 ============
|
|
40
|
+
|
|
41
|
+
private resolveTableForInsert(data: Record<string, any>, sqlSimpleName: KeysOfSimpleSQL): string {
|
|
42
|
+
const context: IShardingRouterContext = { config: this.config, data, sqlSimpleName };
|
|
43
|
+
const result = this.config.customRouter!(context);
|
|
44
|
+
if (Array.isArray(result)) {
|
|
45
|
+
if (result.length === 1) {
|
|
46
|
+
return result[0];
|
|
47
|
+
}
|
|
48
|
+
throw new Error(
|
|
49
|
+
`[ShardingByCustomCrud] 插入操作需要 customRouter 返回单个表名,但返回了 ${result.length} 个: ${result.slice(0, 5).join(', ')}`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (typeof result === 'string' && result) {
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
throw new Error('[ShardingByCustomCrud] 插入操作需要 customRouter 返回单个表名, 实际返回了空值');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private resolveTableForCondition(condition: Record<string, any>, sqlSimpleName: KeysOfSimpleSQL): string {
|
|
59
|
+
const context: IShardingRouterContext = { config: this.config, condition, sqlSimpleName };
|
|
60
|
+
const result = this.config.customRouter!(context);
|
|
61
|
+
if (Array.isArray(result)) {
|
|
62
|
+
if (result.length === 1) return result[0];
|
|
63
|
+
throw new Error(
|
|
64
|
+
`[ShardingByCustomCrud] 写操作需要 customRouter 返回单个表名,但返回了 ${result.length} 个: ${result.slice(0, 5).join(', ')}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async resolveFindTables(reqJson: IRequestModel, sqlSimpleName: KeysOfSimpleSQL): Promise<string[]> {
|
|
71
|
+
const context: IShardingRouterContext = { config: this.config, condition: reqJson.condition, sqlSimpleName };
|
|
72
|
+
const result = this.config.customRouter!(context);
|
|
73
|
+
const candidates = Array.isArray(result) ? result : [result];
|
|
74
|
+
return this.filterExistingTables(candidates);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============ 写操作 ============
|
|
78
|
+
|
|
79
|
+
public async insert(reqJson: IRequestModel): Promise<CrudWriteResult> {
|
|
80
|
+
const targetTable = this.resolveTableForInsert(reqJson.data as Record<string, any>, KeysOfSimpleSQL.SIMPLE_INSERT);
|
|
81
|
+
await this.createShardingTableIfNeeded(targetTable);
|
|
82
|
+
|
|
83
|
+
const ctx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_INSERT);
|
|
84
|
+
const affected = ctx.getResModel().affected || { affectedRows: 0 };
|
|
85
|
+
return new CrudWriteResult({ affectedRows: affected.affectedRows, insertId: affected.insertId, rawContext: ctx });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public async batchInsert(reqJson: IRequestModel): Promise<ShardingBatchInsertResult> {
|
|
89
|
+
const dataArray = reqJson.data as Record<string, any>[];
|
|
90
|
+
if (!Array.isArray(dataArray) || dataArray.length === 0) {
|
|
91
|
+
throw new Error('[ShardingByCustomCrud] batchInsert requires non-empty data array');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const groupedData = new Map<string, Record<string, any>[]>();
|
|
95
|
+
for (const item of dataArray) {
|
|
96
|
+
const table = this.resolveTableForInsert(item, KeysOfSimpleSQL.SIMPLE_BATCH_INSERT);
|
|
97
|
+
if (!groupedData.has(table)) groupedData.set(table, []);
|
|
98
|
+
groupedData.get(table)!.push(item);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const tableName of groupedData.keys()) {
|
|
102
|
+
await this.createShardingTableIfNeeded(tableName);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const results: Array<{ table: string; affected: number; rowCount: number; error: Error | null; context: ExecuteContext | null }> = [];
|
|
106
|
+
let lastContext: ExecuteContext | null = null;
|
|
107
|
+
|
|
108
|
+
for (const [table, items] of groupedData.entries()) {
|
|
109
|
+
try {
|
|
110
|
+
const ctx = await this.executeOnTable(table, { data: items }, KeysOfSimpleSQL.SIMPLE_BATCH_INSERT);
|
|
111
|
+
lastContext = ctx;
|
|
112
|
+
results.push({ table, affected: ctx.getResModelItem('affected')?.affectedRows || items.length, rowCount: items.length, error: null, context: ctx });
|
|
113
|
+
} catch (e) {
|
|
114
|
+
results.push({ table, affected: 0, rowCount: items.length, error: e as Error, context: null });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const tableResults = results.map(r => ({ table: r.table, affected: r.affected, rowCount: r.rowCount }));
|
|
119
|
+
const errors = results.filter(r => r.error !== null).map(r => ({ table: r.table, error: r.error! }));
|
|
120
|
+
const totalAffected = results.reduce((sum, r) => sum + r.affected, 0);
|
|
121
|
+
const finalContext = lastContext || results.find(r => r.context)?.context;
|
|
122
|
+
if (!finalContext) throw new Error('[ShardingByCustomCrud] batchInsert failed - no successful inserts');
|
|
123
|
+
|
|
124
|
+
return new ShardingBatchInsertResult({ totalAffected, tableResults, tableCount: groupedData.size, success: errors.length === 0, errors, lastContext: finalContext });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public async update(reqJson: IRequestModel): Promise<CrudWriteResult> {
|
|
128
|
+
const targetTable = this.resolveTableForCondition(reqJson.condition!, KeysOfSimpleSQL.SIMPLE_UPDATE);
|
|
129
|
+
const ctx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_UPDATE);
|
|
130
|
+
const affected = ctx.getResModel().affected || { affectedRows: 0 };
|
|
131
|
+
return new CrudWriteResult({ affectedRows: affected.affectedRows, insertId: affected.insertId, rawContext: ctx });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public async delete(reqJson: IRequestModel): Promise<CrudWriteResult> {
|
|
135
|
+
const targetTable = this.resolveTableForCondition(reqJson.condition!, KeysOfSimpleSQL.SIMPLE_DELETE);
|
|
136
|
+
const ctx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_DELETE);
|
|
137
|
+
const affected = ctx.getResModel().affected || { affectedRows: 0 };
|
|
138
|
+
return new CrudWriteResult({ affectedRows: affected.affectedRows, insertId: affected.insertId, rawContext: ctx });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public async restore(reqJson: IRequestModel): Promise<CrudWriteResult> {
|
|
142
|
+
const targetTable = this.resolveTableForCondition(reqJson.condition!, KeysOfSimpleSQL.SIMPLE_UPDATE);
|
|
143
|
+
if (!reqJson.condition || Object.keys(reqJson.condition).length === 0) {
|
|
144
|
+
throw new Error('[ShardingByCustomCrud] restore 操作必须指定恢复条件');
|
|
145
|
+
}
|
|
146
|
+
const restoreReqJson: IRequestModel = {
|
|
147
|
+
...reqJson,
|
|
148
|
+
data: { ...reqJson.data, deleted_at: 0, deleted_by: '' },
|
|
149
|
+
};
|
|
150
|
+
const ctx = await this.executeOnTable(targetTable, restoreReqJson, KeysOfSimpleSQL.SIMPLE_UPDATE);
|
|
151
|
+
const affected = ctx.getResModel().affected || { affectedRows: 0 };
|
|
152
|
+
return new CrudWriteResult({ affectedRows: affected.affectedRows, insertId: affected.insertId, rawContext: ctx });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public async insertOrUpdate(reqJson: IRequestModel): Promise<CrudUpsertResult> {
|
|
156
|
+
const targetTable = this.resolveTableForCondition(reqJson.condition!, KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE);
|
|
157
|
+
|
|
158
|
+
const existCtx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_EXIST);
|
|
159
|
+
const isExist = existCtx.getResModelItem('is_exist') === true;
|
|
160
|
+
|
|
161
|
+
if (isExist) {
|
|
162
|
+
const updateCtx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_UPDATE);
|
|
163
|
+
return new CrudUpsertResult({ insertAffected: undefined, updateAffected: updateCtx.getResModel().affected, isExist: true, rawContext: updateCtx });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
await this.createShardingTableIfNeeded(targetTable);
|
|
167
|
+
const insertCtx = await this.executeOnTable(targetTable, reqJson, KeysOfSimpleSQL.SIMPLE_INSERT);
|
|
168
|
+
return new CrudUpsertResult({ insertAffected: insertCtx.getResModel().affected, updateAffected: undefined, isExist: false, rawContext: insertCtx });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ============ 查询操作 ============
|
|
172
|
+
|
|
173
|
+
public async findOne<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryOneResult<T>> {
|
|
174
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_ONE);
|
|
175
|
+
if (targetTables.length === 0) throw new Error('[ShardingByCustomCrud] findOne: no matching tables found');
|
|
176
|
+
|
|
177
|
+
let lastCtx: ExecuteContext | null = null;
|
|
178
|
+
let lastTable: string | undefined;
|
|
179
|
+
for (const table of targetTables) {
|
|
180
|
+
try {
|
|
181
|
+
const ctx = await this.executeOnTable(table, reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_ONE);
|
|
182
|
+
lastCtx = ctx; lastTable = table;
|
|
183
|
+
const row = ctx.getOneObj();
|
|
184
|
+
if (row) return new CrudQueryOneResult<T>({ row: row as T, rawContext: ctx, debugInfo: this.buildDebugInfo(table, reqJson.condition), fromTable: table });
|
|
185
|
+
} catch (e) { /* skip */ }
|
|
186
|
+
}
|
|
187
|
+
return new CrudQueryOneResult<T>({ row: null, rawContext: lastCtx, debugInfo: this.buildDebugInfo(targetTables[0], reqJson.condition), fromTable: lastTable });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public async findUniqueOne<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryOneResult<T>> {
|
|
191
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_ONE);
|
|
192
|
+
if (targetTables.length === 0) {
|
|
193
|
+
return new CrudQueryOneResult<T>({ row: null, rawContext: null as any, debugInfo: this.buildDebugInfo(undefined, reqJson.condition), fromTable: null });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const allRows: T[] = [];
|
|
197
|
+
const foundTables: string[] = [];
|
|
198
|
+
let firstCtx: ExecuteContext | null = null;
|
|
199
|
+
|
|
200
|
+
for (const table of targetTables) {
|
|
201
|
+
try {
|
|
202
|
+
const ctx = await this.executeOnTable(table, reqJson, KeysOfSimpleSQL.SIMPLE_QUERY, { maxLimit: 2 });
|
|
203
|
+
if (!firstCtx) firstCtx = ctx;
|
|
204
|
+
const rows = ctx.getResRows() as T[];
|
|
205
|
+
if (rows.length > 0) {
|
|
206
|
+
allRows.push(...rows);
|
|
207
|
+
foundTables.push(table);
|
|
208
|
+
if (allRows.length > 1) throw new Error(this.formatUniqueError(allRows.length, foundTables, reqJson.condition, foundTables.length > 1));
|
|
209
|
+
}
|
|
210
|
+
} catch (e) {
|
|
211
|
+
if (e instanceof Error && e.message.startsWith('[ShardingBase] findUniqueOne')) throw e;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const fromTable = foundTables[0] || null;
|
|
216
|
+
return new CrudQueryOneResult<T>({ row: allRows[0] || null, rawContext: firstCtx, debugInfo: this.buildDebugInfo(fromTable || targetTables[0], reqJson.condition), fromTable: fromTable || targetTables[0] });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
public async findList<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryListResult<T>> {
|
|
220
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY);
|
|
221
|
+
if (targetTables.length === 0) return new CrudQueryListResult<T>({ rows: [], rawContext: null as any });
|
|
222
|
+
|
|
223
|
+
if (targetTables.length === 1) {
|
|
224
|
+
const ctx = await this.executeOnTable(targetTables[0], reqJson, KeysOfSimpleSQL.SIMPLE_QUERY);
|
|
225
|
+
return new CrudQueryListResult<T>({ rows: ctx.getResRows() as T[], rawContext: ctx });
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let allRows: any[] = [];
|
|
229
|
+
let lastCtx: ExecuteContext | null = null;
|
|
230
|
+
for (const table of targetTables) {
|
|
231
|
+
try {
|
|
232
|
+
const ctx = await this.executeOnTable(table, reqJson, KeysOfSimpleSQL.SIMPLE_QUERY);
|
|
233
|
+
lastCtx = ctx;
|
|
234
|
+
allRows = allRows.concat(ctx.getResRows() || []);
|
|
235
|
+
} catch (e) { /* skip */ }
|
|
236
|
+
}
|
|
237
|
+
return new CrudQueryListResult<T>({ rows: allRows as T[], rawContext: lastCtx });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
public async findPage<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryPageResult<T>> {
|
|
241
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_PAGE);
|
|
242
|
+
if (targetTables.length === 0) throw new Error('[ShardingByCustomCrud] findPage: no matching tables found');
|
|
243
|
+
|
|
244
|
+
if (targetTables.length === 1) {
|
|
245
|
+
const ctx = await this.executeOnTable(targetTables[0], reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_PAGE);
|
|
246
|
+
const pageResult = ctx.getResModelForQueryPage();
|
|
247
|
+
return new CrudQueryPageResult<T>({ rows: pageResult.rows as T[], totalCount: pageResult.total_count, rawContext: ctx });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const { pageNo = 1, pageSize = 10 } = reqJson;
|
|
251
|
+
const offset = (pageNo - 1) * pageSize;
|
|
252
|
+
|
|
253
|
+
let totalCount = 0;
|
|
254
|
+
const tableCounts: Array<{ table: string; count: number }> = [];
|
|
255
|
+
for (const table of targetTables) {
|
|
256
|
+
const { count } = await this.findCountFromTable(table, reqJson);
|
|
257
|
+
tableCounts.push({ table, count });
|
|
258
|
+
totalCount += count;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (totalCount === 0) {
|
|
262
|
+
return new CrudQueryPageResult<T>({ rows: [], totalCount: 0, rawContext: null as any });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let accumulated = 0;
|
|
266
|
+
let allRows: any[] = [];
|
|
267
|
+
let lastCtx: ExecuteContext | null = null;
|
|
268
|
+
const targetEnd = offset + pageSize;
|
|
269
|
+
|
|
270
|
+
for (const { table, count } of tableCounts) {
|
|
271
|
+
if (count === 0) continue;
|
|
272
|
+
const tableEnd = accumulated + count;
|
|
273
|
+
if (tableEnd <= offset) { accumulated = tableEnd; continue; }
|
|
274
|
+
if (accumulated >= targetEnd) break;
|
|
275
|
+
|
|
276
|
+
const innerOffset = Math.max(0, offset - accumulated);
|
|
277
|
+
const innerLimit = Math.min(count, targetEnd - accumulated) - innerOffset;
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
const ctx = await this.executeOnTable(table, { ...reqJson, offset: innerOffset, limit: innerLimit } as any, KeysOfSimpleSQL.SIMPLE_QUERY);
|
|
281
|
+
lastCtx = ctx;
|
|
282
|
+
allRows = allRows.concat(ctx.getResRows() || []);
|
|
283
|
+
} catch (e) { /* skip */ }
|
|
284
|
+
|
|
285
|
+
accumulated = tableEnd;
|
|
286
|
+
if (accumulated >= targetEnd) break;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return new CrudQueryPageResult<T>({ rows: allRows as T[], totalCount, rawContext: lastCtx });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public async findCount(reqJson: IRequestModel): Promise<CrudCountResult> {
|
|
293
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_COUNT);
|
|
294
|
+
if (targetTables.length === 0) throw new Error('[ShardingByCustomCrud] findCount: no matching tables found');
|
|
295
|
+
|
|
296
|
+
if (targetTables.length === 1) {
|
|
297
|
+
const ctx = await this.executeOnTable(targetTables[0], reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_COUNT);
|
|
298
|
+
return new CrudCountResult({ count: ctx.getResModelItem('total_count') || 0, rawContext: ctx });
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
let totalCount = 0;
|
|
302
|
+
let firstCtx: ExecuteContext | null = null;
|
|
303
|
+
for (const table of targetTables) {
|
|
304
|
+
const { count, ctx } = await this.findCountFromTable(table, reqJson);
|
|
305
|
+
totalCount += count;
|
|
306
|
+
if (!firstCtx && ctx) firstCtx = ctx;
|
|
307
|
+
}
|
|
308
|
+
return new CrudCountResult({ count: totalCount, rawContext: firstCtx as any });
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
public async isExist(reqJson: IRequestModel): Promise<CrudExistResult> {
|
|
312
|
+
const targetTables = await this.resolveFindTables(reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_EXIST);
|
|
313
|
+
if (targetTables.length === 0) throw new Error('[ShardingByCustomCrud] isExist: no matching tables found');
|
|
314
|
+
|
|
315
|
+
if (targetTables.length === 1) {
|
|
316
|
+
const ctx = await this.executeOnTable(targetTables[0], reqJson, KeysOfSimpleSQL.SIMPLE_QUERY_EXIST);
|
|
317
|
+
return new CrudExistResult({ exists: ctx.getResModelItem('is_exist') === true, rawContext: ctx });
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
let exists = false;
|
|
321
|
+
let firstCtx: ExecuteContext | null = null;
|
|
322
|
+
for (const table of targetTables) {
|
|
323
|
+
const result = await this.isExistInTable(table, reqJson);
|
|
324
|
+
if (!firstCtx && result.ctx) firstCtx = result.ctx;
|
|
325
|
+
if (result.exists) { exists = true; break; }
|
|
326
|
+
}
|
|
327
|
+
return new CrudExistResult({ exists, rawContext: firstCtx as any });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { IRequestModel, IRequestCfgModel } from '@/libs/crud-pro/interfaces';
|
|
2
|
+
import { IShardingConfig, IShardingRouterContext, CrudProFactory } from './ShardingConfig';
|
|
3
|
+
import { ShardingBase } from './ShardingBase';
|
|
4
|
+
import { ShardingByCustomCrud } from './ShardingByCustomCrud';
|
|
5
|
+
import {
|
|
6
|
+
CrudWriteResult,
|
|
7
|
+
CrudQueryOneResult,
|
|
8
|
+
CrudQueryListResult,
|
|
9
|
+
CrudQueryPageResult,
|
|
10
|
+
CrudExistResult,
|
|
11
|
+
CrudCountResult,
|
|
12
|
+
CrudUpsertResult,
|
|
13
|
+
} from '@/libs/crud-pro/models/CrudResult';
|
|
14
|
+
import { ShardingBatchInsertResult } from './ShardingResult';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 哈希分表 CRUD
|
|
18
|
+
*
|
|
19
|
+
* 根据 shardingColumn 的哈希值取模 tableCount,定位到固定数量的分表。
|
|
20
|
+
* 表名格式:baseTable_XX(如 t_order_00 ~ t_order_15)
|
|
21
|
+
*
|
|
22
|
+
* 内部委托 ShardingByCustomCrud 实现所有 CRUD 操作,
|
|
23
|
+
* 通过 customRouter 实现哈希路由逻辑。
|
|
24
|
+
*
|
|
25
|
+
* 规范:所有操作必须提供 shardingColumn,否则抛出异常。
|
|
26
|
+
*
|
|
27
|
+
* 特性:
|
|
28
|
+
* - 路由:hash(shardingColumn) % tableCount → 固定分表
|
|
29
|
+
* - insertOrUpdate:统一由 condition 路由定位分表
|
|
30
|
+
*/
|
|
31
|
+
export class ShardingByHashCrud extends ShardingBase {
|
|
32
|
+
private delegate: ShardingByCustomCrud;
|
|
33
|
+
|
|
34
|
+
constructor(crudProFactory: CrudProFactory, config: IShardingConfig) {
|
|
35
|
+
super(crudProFactory, config);
|
|
36
|
+
|
|
37
|
+
if (!config.shardingColumn) {
|
|
38
|
+
throw new Error('[ShardingByHashCrud] 哈希分表必须指定 shardingColumn');
|
|
39
|
+
}
|
|
40
|
+
if (!config.tableCount || config.tableCount <= 0) {
|
|
41
|
+
throw new Error('[ShardingByHashCrud] 哈希分表必须指定 tableCount(大于 0)');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const col = config.shardingColumn;
|
|
45
|
+
const count = config.tableCount;
|
|
46
|
+
const baseTable = config.baseTable;
|
|
47
|
+
const fmt = config.suffixFormatter;
|
|
48
|
+
|
|
49
|
+
/** 格式化表名:baseTable + _ + 后缀(可选 suffixFormatter) */
|
|
50
|
+
const formatTable = (suffix: string): string => {
|
|
51
|
+
const formatted = fmt ? fmt(suffix) : suffix;
|
|
52
|
+
return `${baseTable}_${formatted}`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** djb2 哈希 → 取模 → 零填充后缀 → 表名 */
|
|
56
|
+
const hashRoute = (value: any): string => {
|
|
57
|
+
const str = String(value);
|
|
58
|
+
let hash = 5381;
|
|
59
|
+
for (let i = 0; i < str.length; i++) {
|
|
60
|
+
hash = ((hash << 5) + hash) + str.charCodeAt(i);
|
|
61
|
+
hash = hash & hash;
|
|
62
|
+
}
|
|
63
|
+
return formatTable(String(Math.abs(hash) % count).padStart(2, '0'));
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const customRouter = (ctx: IShardingRouterContext): string => {
|
|
67
|
+
// 根据操作类型确定字段来源:insert 类从 data,其余从 condition
|
|
68
|
+
const fromData = ShardingBase.isInsertPhase(ctx);
|
|
69
|
+
const val = fromData ? ctx.data?.[col] : ctx.condition?.[col];
|
|
70
|
+
|
|
71
|
+
if (val != null && val !== '' && val !== undefined) {
|
|
72
|
+
return hashRoute(val);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
throw new Error(
|
|
76
|
+
`[ShardingByHashCrud] ${fromData ? 'data' : 'condition'} 必须包含分表字段 '${col}'`
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
this.delegate = new ShardingByCustomCrud(crudProFactory, { ...config, customRouter });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ============ 状态同步 ============
|
|
84
|
+
|
|
85
|
+
public setBaseCfg(cfg: Partial<IRequestCfgModel>): this {
|
|
86
|
+
super.setBaseCfg(cfg);
|
|
87
|
+
this.delegate.setBaseCfg(cfg);
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public setEnableSoftDelete(enable: boolean): this {
|
|
92
|
+
super.setEnableSoftDelete(enable);
|
|
93
|
+
this.delegate.setEnableSoftDelete(enable);
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ============ CRUD 方法:全部委托 ============
|
|
98
|
+
|
|
99
|
+
public insert(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.insert(r); }
|
|
100
|
+
public batchInsert(r: IRequestModel): Promise<ShardingBatchInsertResult> { return this.delegate.batchInsert(r); }
|
|
101
|
+
public update(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.update(r); }
|
|
102
|
+
public delete(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.delete(r); }
|
|
103
|
+
public restore(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.restore(r); }
|
|
104
|
+
public insertOrUpdate(r: IRequestModel): Promise<CrudUpsertResult> { return this.delegate.insertOrUpdate(r); }
|
|
105
|
+
public findOne<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryOneResult<T>> { return this.delegate.findOne<T>(r); }
|
|
106
|
+
public findUniqueOne<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryOneResult<T>> { return this.delegate.findUniqueOne<T>(r); }
|
|
107
|
+
public findList<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryListResult<T>> { return this.delegate.findList<T>(r); }
|
|
108
|
+
public findPage<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryPageResult<T>> { return this.delegate.findPage<T>(r); }
|
|
109
|
+
public findCount(r: IRequestModel): Promise<CrudCountResult> { return this.delegate.findCount(r); }
|
|
110
|
+
public isExist(r: IRequestModel): Promise<CrudExistResult> { return this.delegate.isExist(r); }
|
|
111
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { IRequestModel, IRequestCfgModel } from '@/libs/crud-pro/interfaces';
|
|
2
|
+
import { IShardingConfig, IShardingRouterContext, CrudProFactory } from './ShardingConfig';
|
|
3
|
+
import { ShardingBase } from './ShardingBase';
|
|
4
|
+
import { ShardingByCustomCrud } from './ShardingByCustomCrud';
|
|
5
|
+
import {
|
|
6
|
+
CrudWriteResult,
|
|
7
|
+
CrudQueryOneResult,
|
|
8
|
+
CrudQueryListResult,
|
|
9
|
+
CrudQueryPageResult,
|
|
10
|
+
CrudExistResult,
|
|
11
|
+
CrudCountResult,
|
|
12
|
+
CrudUpsertResult,
|
|
13
|
+
} from '@/libs/crud-pro/models/CrudResult';
|
|
14
|
+
import { ShardingBatchInsertResult } from './ShardingResult';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 键值分表 CRUD
|
|
18
|
+
*
|
|
19
|
+
* 字段原值即表后缀,一值一表。
|
|
20
|
+
* 表名格式:baseTable_{shardingColumn值}(如 t_log_east, t_log_west)
|
|
21
|
+
*
|
|
22
|
+
* 内部委托 ShardingByCustomCrud 实现所有 CRUD 操作,
|
|
23
|
+
* 通过 customRouter 实现键值路由逻辑。
|
|
24
|
+
*
|
|
25
|
+
* 规范:所有操作必须提供 shardingColumn,否则抛出异常。
|
|
26
|
+
*
|
|
27
|
+
* 特性:
|
|
28
|
+
* - 路由:shardingColumn 的原始值直接作为表后缀
|
|
29
|
+
* - 不预定义 keyValues,表按需动态创建
|
|
30
|
+
* - insertOrUpdate:统一由 condition 路由定位分表
|
|
31
|
+
*/
|
|
32
|
+
export class ShardingByKeyCrud extends ShardingBase {
|
|
33
|
+
private delegate: ShardingByCustomCrud;
|
|
34
|
+
|
|
35
|
+
constructor(crudProFactory: CrudProFactory, config: IShardingConfig) {
|
|
36
|
+
super(crudProFactory, config);
|
|
37
|
+
|
|
38
|
+
if (!config.shardingColumn) {
|
|
39
|
+
throw new Error('[ShardingByKeyCrud] 键值分表必须指定 shardingColumn');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const col = config.shardingColumn;
|
|
43
|
+
const baseTable = config.baseTable;
|
|
44
|
+
const fmt = config.suffixFormatter;
|
|
45
|
+
|
|
46
|
+
/** 格式化表名:baseTable + _ + 后缀(可选 suffixFormatter) */
|
|
47
|
+
const formatTable = (suffix: string): string => {
|
|
48
|
+
const formatted = fmt ? fmt(suffix) : suffix;
|
|
49
|
+
return `${baseTable}_${formatted}`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const customRouter = (ctx: IShardingRouterContext): string | string[] => {
|
|
53
|
+
// 根据操作类型确定字段来源:insert 类从 data,其余从 condition
|
|
54
|
+
const fromData = ShardingBase.isInsertPhase(ctx);
|
|
55
|
+
const val = fromData ? ctx.data?.[col] : ctx.condition?.[col];
|
|
56
|
+
|
|
57
|
+
if (val != null && val !== '' && val !== undefined) {
|
|
58
|
+
return formatTable(String(val))
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
throw new Error(
|
|
62
|
+
`[ShardingByKeyCrud] ${fromData ? 'data' : 'condition'} 必须包含分表字段 '${col}'`
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
this.delegate = new ShardingByCustomCrud(crudProFactory, { ...config, customRouter });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ============ 状态同步 ============
|
|
70
|
+
|
|
71
|
+
public setBaseCfg(cfg: Partial<IRequestCfgModel>): this {
|
|
72
|
+
super.setBaseCfg(cfg);
|
|
73
|
+
this.delegate.setBaseCfg(cfg);
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public setEnableSoftDelete(enable: boolean): this {
|
|
78
|
+
super.setEnableSoftDelete(enable);
|
|
79
|
+
this.delegate.setEnableSoftDelete(enable);
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ============ CRUD 方法:全部委托 ============
|
|
84
|
+
|
|
85
|
+
public insert(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.insert(r); }
|
|
86
|
+
public batchInsert(r: IRequestModel): Promise<ShardingBatchInsertResult> { return this.delegate.batchInsert(r); }
|
|
87
|
+
public update(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.update(r); }
|
|
88
|
+
public delete(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.delete(r); }
|
|
89
|
+
public restore(r: IRequestModel): Promise<CrudWriteResult> { return this.delegate.restore(r); }
|
|
90
|
+
public insertOrUpdate(r: IRequestModel): Promise<CrudUpsertResult> { return this.delegate.insertOrUpdate(r); }
|
|
91
|
+
public findOne<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryOneResult<T>> { return this.delegate.findOne<T>(r); }
|
|
92
|
+
public findUniqueOne<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryOneResult<T>> { return this.delegate.findUniqueOne<T>(r); }
|
|
93
|
+
public findList<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryListResult<T>> { return this.delegate.findList<T>(r); }
|
|
94
|
+
public findPage<T = Record<string, any>>(r: IRequestModel): Promise<CrudQueryPageResult<T>> { return this.delegate.findPage<T>(r); }
|
|
95
|
+
public findCount(r: IRequestModel): Promise<CrudCountResult> { return this.delegate.findCount(r); }
|
|
96
|
+
public isExist(r: IRequestModel): Promise<CrudExistResult> { return this.delegate.isExist(r); }
|
|
97
|
+
}
|