midway-fatcms 0.0.5 → 0.0.7

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 (132) hide show
  1. package/.qoder/skills/midway-fatcms-crud/SKILL.md +375 -0
  2. package/.qoder/skills/midway-fatcms-crud/examples.md +990 -0
  3. package/.qoder/skills/midway-fatcms-crud/reference.md +568 -0
  4. package/README.md +377 -134
  5. package/dist/controller/manage/CrudStandardDesignApi.d.ts +0 -2
  6. package/dist/controller/manage/CrudStandardDesignApi.js +11 -85
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.js +2 -0
  9. package/dist/libs/crud-pro/CrudPro.d.ts +9 -1
  10. package/dist/libs/crud-pro/CrudPro.js +15 -0
  11. package/dist/libs/crud-pro/README.md +809 -0
  12. package/dist/libs/crud-pro/README_FUNC.md +193 -0
  13. package/dist/libs/crud-pro/exceptions.d.ts +2 -0
  14. package/dist/libs/crud-pro/exceptions.js +2 -0
  15. package/dist/libs/crud-pro/interfaces.d.ts +34 -1
  16. package/dist/libs/crud-pro/models/ExecuteContext.d.ts +3 -3
  17. package/dist/libs/crud-pro/models/ExecuteContext.js +2 -0
  18. package/dist/libs/crud-pro/models/RequestModel.d.ts +6 -2
  19. package/dist/libs/crud-pro/models/RequestModel.js +20 -53
  20. package/dist/libs/crud-pro/models/ResModel.d.ts +6 -4
  21. package/dist/libs/crud-pro/models/ServiceHub.d.ts +1 -0
  22. package/dist/libs/crud-pro/models/keys.d.ts +6 -1
  23. package/dist/libs/crud-pro/models/keys.js +5 -0
  24. package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +52 -0
  25. package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +158 -0
  26. package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +20 -1
  27. package/dist/libs/crud-pro/services/CrudProFieldValidateService.d.ts +7 -0
  28. package/dist/libs/crud-pro/services/CrudProFieldValidateService.js +32 -0
  29. package/dist/libs/crud-pro/services/CrudProGenSqlService.d.ts +13 -0
  30. package/dist/libs/crud-pro/services/CrudProGenSqlService.js +44 -7
  31. package/dist/libs/crud-pro/services/CrudProOriginToExecuteSql.d.ts +43 -0
  32. package/dist/libs/crud-pro/services/CrudProOriginToExecuteSql.js +132 -1
  33. package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +15 -1
  34. package/dist/libs/crud-pro/services/CrudProTableMetaService.js +107 -0
  35. package/dist/libs/crud-pro/services/CurdProServiceHub.d.ts +5 -1
  36. package/dist/libs/crud-pro/services/CurdProServiceHub.js +11 -0
  37. package/dist/libs/crud-pro/utils/DateTimeUtils.d.ts +1 -0
  38. package/dist/libs/crud-pro/utils/DateTimeUtils.js +3 -0
  39. package/dist/libs/crud-pro/utils/MixinUtils.d.ts +32 -0
  40. package/dist/libs/crud-pro/utils/MixinUtils.js +85 -1
  41. package/dist/libs/crud-pro/utils/OrderByUtils.d.ts +70 -0
  42. package/dist/libs/crud-pro/utils/OrderByUtils.js +158 -0
  43. package/dist/libs/crud-pro/utils/ValidateUtils.js +1 -1
  44. package/dist/libs/crud-sharding/ROUTING_LOGIC.md +944 -0
  45. package/dist/libs/crud-sharding/ShardingConfig.d.ts +218 -0
  46. package/dist/libs/crud-sharding/ShardingConfig.js +32 -0
  47. package/dist/libs/crud-sharding/ShardingCountCache.d.ts +69 -0
  48. package/dist/libs/crud-sharding/ShardingCountCache.js +160 -0
  49. package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +363 -0
  50. package/dist/libs/crud-sharding/ShardingCrudPro.js +675 -0
  51. package/dist/libs/crud-sharding/ShardingMerger.d.ts +130 -0
  52. package/dist/libs/crud-sharding/ShardingMerger.js +282 -0
  53. package/dist/libs/crud-sharding/ShardingRouter.d.ts +69 -0
  54. package/dist/libs/crud-sharding/ShardingRouter.js +377 -0
  55. package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +146 -0
  56. package/dist/libs/crud-sharding/ShardingTableCreator.js +805 -0
  57. package/dist/libs/crud-sharding/ShardingUtils.d.ts +38 -0
  58. package/dist/libs/crud-sharding/ShardingUtils.js +77 -0
  59. package/dist/libs/crud-sharding/index.d.ts +45 -0
  60. package/dist/libs/crud-sharding/index.js +55 -0
  61. package/dist/models/StandardColumns.d.ts +71 -0
  62. package/dist/models/StandardColumns.js +28 -0
  63. package/dist/service/SysAppService.js +2 -2
  64. package/dist/service/SysConfigService.js +1 -1
  65. package/dist/service/SysDictDataService.js +2 -2
  66. package/dist/service/SysMenuService.js +1 -1
  67. package/dist/service/UserAccountService.d.ts +1 -1
  68. package/dist/service/crudstd/CrudStdService.d.ts +0 -1
  69. package/dist/service/crudstd/CrudStdService.js +0 -27
  70. package/dist/service/curd/CrudProQuick.d.ts +134 -4
  71. package/dist/service/curd/CrudProQuick.js +155 -3
  72. package/dist/service/curd/CurdMixService.d.ts +2 -1
  73. package/dist/service/curd/CurdMixService.js +5 -1
  74. package/dist/service/curd/CurdProService.d.ts +44 -2
  75. package/dist/service/curd/CurdProService.js +53 -1
  76. package/dist/service/curd/README.md +1100 -0
  77. package/dist/service/curd/fixSoftDelete.d.ts +14 -0
  78. package/dist/service/curd/fixSoftDelete.js +29 -11
  79. package/dist/service/flow/FlowConfigService.js +1 -1
  80. package/dist/service/flow/FlowInstanceCrudService.js +1 -1
  81. package/package.json +4 -1
  82. package/src/controller/gateway/AsyncTaskController.ts +1 -1
  83. package/src/controller/manage/CrudStandardDesignApi.ts +16 -100
  84. package/src/index.ts +3 -0
  85. package/src/libs/crud-pro/CrudPro.ts +19 -1
  86. package/src/libs/crud-pro/README.md +809 -0
  87. package/src/libs/crud-pro/README_FUNC.md +193 -0
  88. package/src/libs/crud-pro/exceptions.ts +2 -0
  89. package/src/libs/crud-pro/interfaces.ts +38 -1
  90. package/src/libs/crud-pro/models/ExecuteContext.ts +6 -3
  91. package/src/libs/crud-pro/models/RequestModel.ts +23 -65
  92. package/src/libs/crud-pro/models/ResModel.ts +10 -4
  93. package/src/libs/crud-pro/models/ServiceHub.ts +2 -0
  94. package/src/libs/crud-pro/models/keys.ts +5 -0
  95. package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +171 -0
  96. package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +24 -1
  97. package/src/libs/crud-pro/services/CrudProFieldValidateService.ts +53 -1
  98. package/src/libs/crud-pro/services/CrudProGenSqlService.ts +51 -7
  99. package/src/libs/crud-pro/services/CrudProOriginToExecuteSql.ts +159 -2
  100. package/src/libs/crud-pro/services/CrudProTableMetaService.ts +139 -1
  101. package/src/libs/crud-pro/services/CurdProServiceHub.ts +16 -1
  102. package/src/libs/crud-pro/utils/DateTimeUtils.ts +3 -0
  103. package/src/libs/crud-pro/utils/MixinUtils.ts +97 -1
  104. package/src/libs/crud-pro/utils/OrderByUtils.ts +169 -0
  105. package/src/libs/crud-pro/utils/ValidateUtils.ts +1 -1
  106. package/src/libs/crud-sharding/ROUTING_LOGIC.md +944 -0
  107. package/src/libs/crud-sharding/ShardingConfig.ts +240 -0
  108. package/src/libs/crud-sharding/ShardingCountCache.ts +200 -0
  109. package/src/libs/crud-sharding/ShardingCrudPro.ts +835 -0
  110. package/src/libs/crud-sharding/ShardingMerger.ts +384 -0
  111. package/src/libs/crud-sharding/ShardingRouter.ts +512 -0
  112. package/src/libs/crud-sharding/ShardingTableCreator.ts +1007 -0
  113. package/src/libs/crud-sharding/ShardingUtils.ts +84 -0
  114. package/src/libs/crud-sharding/index.ts +64 -0
  115. package/src/models/StandardColumns.ts +76 -0
  116. package/src/service/FileCenterService.ts +1 -1
  117. package/src/service/SysAppService.ts +2 -2
  118. package/src/service/SysConfigService.ts +1 -1
  119. package/src/service/SysDictDataService.ts +2 -2
  120. package/src/service/SysMenuService.ts +2 -2
  121. package/src/service/WorkbenchService.ts +1 -1
  122. package/src/service/anyapi/AnyApiService.ts +1 -1
  123. package/src/service/asyncTask/AsyncTaskRunnerService.ts +1 -1
  124. package/src/service/crudstd/CrudStdService.ts +0 -32
  125. package/src/service/curd/CrudProQuick.ts +164 -5
  126. package/src/service/curd/CurdMixService.ts +7 -2
  127. package/src/service/curd/CurdProService.ts +62 -3
  128. package/src/service/curd/README.md +1100 -0
  129. package/src/service/curd/fixCfgModel.ts +1 -2
  130. package/src/service/curd/fixSoftDelete.ts +38 -16
  131. package/src/service/flow/FlowConfigService.ts +1 -1
  132. package/src/service/flow/FlowInstanceCrudService.ts +1 -1
@@ -0,0 +1,568 @@
1
+ # midway-fatcms 完整参考手册
2
+
3
+ ## CrudProQuick API 参考
4
+
5
+ ### 查询类方法
6
+
7
+ | 方法 | 参数 | 返回类型 | 说明 |
8
+ |------|------|----------|------|
9
+ | `getList(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `any[]` | 列表查询 |
10
+ | `getListPage(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelPageQuery` | 分页查询(含 total_count) |
11
+ | `getUniqueOne(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `any \| null` | 期望唯一一条,0条返回null,多条报错 |
12
+ | `getOne(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `any` | 获取第一条(已废弃,建议用 getUniqueOne) |
13
+ | `isExist(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `boolean` | 存在性判断(比 COUNT 高效) |
14
+ | `getTotalCount(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `number` | 统计总数 |
15
+
16
+ ### 写入类方法
17
+
18
+ | 方法 | 参数 | 返回类型 | 说明 |
19
+ |------|------|----------|------|
20
+ | `insertObject(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelAffected` | 插入单条 |
21
+ | `batchInsert(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelAffected` | 批量插入 |
22
+ | `updateObject(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelAffected` | 更新 |
23
+ | `insertOrUpdate(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelStandard` | 先查询存在性,再决定插入或更新 |
24
+ | `insertOnDuplicate(reqJson, uniqueColumn?, sqlTable?)` | `IRequestModel`, `string[]?`, `string?` | `ResModelAffected` | 原生 upsert(MySQL: ON DUPLICATE KEY UPDATE) |
25
+ | `deleteObject(reqJson, sqlTable?)` | `IRequestModel`, `string?` | `ResModelAffected` | 删除(受软删除配置影响) |
26
+
27
+ ### 原生 SQL 方法
28
+
29
+ | 方法 | 参数 | 返回类型 | 说明 |
30
+ |------|------|----------|------|
31
+ | `executeSQL(sql, args?)` | `string`, `any[]?` | `any` | 框架封装的 SQL 执行(带参数绑定) |
32
+ | `executeNativeSQL<T>(sql, args?)` | `string`, `any[]?` | `T` | 原生 SQL 执行,不做额外处理 |
33
+
34
+ ## 请求参数结构 (IRequestModel)
35
+
36
+ ```typescript
37
+ interface IRequestModel {
38
+ method?: string; // Config 方法名
39
+ condition?: Record<string, any>; // 查询/更新/删除条件
40
+ data?: Record<string, any> | Record<string, any>[]; // 插入/更新数据
41
+ pageNo?: number; // 页码(从1开始)
42
+ pageSize?: number; // 每页条数
43
+ orderBy?: string | OrderByItem[]; // 排序规则
44
+ columns?: string | string[]; // 指定返回列
45
+ limit?: number;
46
+ offset?: number;
47
+ }
48
+ ```
49
+
50
+ ## 条件操作符详解
51
+
52
+ ### 比较操作符
53
+
54
+ | 操作符 | 说明 | 示例 |
55
+ |--------|------|------|
56
+ | `$gt` | 大于 | `{ age: { $gt: 18 } }` |
57
+ | `$gte` | 大于等于 | `{ score: { $gte: 60 } }` |
58
+ | `$lt` | 小于 | `{ price: { $lt: 100 } }` |
59
+ | `$lte` | 小于等于 | `{ count: { $lte: 10 } }` |
60
+ | `$ne` | 不等于 | `{ status: { $ne: 'deleted' } }` |
61
+ | `$eq` | 等于(显式) | `{ status: { $eq: 'active' } }` |
62
+
63
+ ### 范围操作符
64
+
65
+ | 操作符 | 说明 | 示例 |
66
+ |--------|------|------|
67
+ | `$in` | IN 查询 | `{ id: { $in: [1, 2, 3] } }` |
68
+ | `$nin` | NOT IN | `{ type: { $nin: ['test'] } }` |
69
+ | `$between` / `$range` | BETWEEN | `{ amount: { $between: [100, 500] } }` |
70
+
71
+ ### 模糊查询
72
+
73
+ | 操作符 | 说明 | 示例 |
74
+ |--------|------|------|
75
+ | `$like` | 前缀匹配 LIKE 'A%' | `{ name: { $like: '张' } }` |
76
+ | `$notLike` | 非前缀匹配 | `{ name: { $notLike: 'test' } }` |
77
+ | `$likeInclude` | 包含匹配 LIKE '%A%' | `{ name: { $likeInclude: '张三' } }` |
78
+ | `$notLikeInclude` | 不包含匹配 | `{ name: { $notLikeInclude: 'test' } }` |
79
+
80
+ ### NULL 判断
81
+
82
+ | 操作符 | 说明 | 示例 |
83
+ |--------|------|------|
84
+ | `$isNull` / `$null` | IS NULL | `{ deleted_at: { $isNull: true } }` |
85
+ | `$isNotNull` / `$notNull` | IS NOT NULL | `{ phone: { $isNotNull: true } }` |
86
+
87
+ ### 全文搜索
88
+
89
+ | 操作符 | 说明 | 示例 |
90
+ |--------|------|------|
91
+ | `$match` | MySQL 全文搜索 | `{ content: { $match: 'keyword' } }` |
92
+ | `$matchBool` | MySQL 布尔全文搜索 | `{ content: { $matchBool: '+keyword -exclude' } }` |
93
+
94
+ ### JSON 操作
95
+
96
+ | 操作符 | 说明 | 示例 |
97
+ |--------|------|------|
98
+ | `$jsonArrayContains` | JSON 数组包含 | `{ tags: { $jsonArrayContains: 'tag1' } }` |
99
+
100
+ ### 逻辑组合
101
+
102
+ ```typescript
103
+ // AND 条件(默认)
104
+ { $and: [{ status: 'active' }, { age: { $gte: 18 } }] }
105
+
106
+ // OR 条件
107
+ { $or: [{ status: 'pending' }, { status: 'processing' }] }
108
+
109
+ // AND + OR 组合
110
+ {
111
+ $and: [
112
+ { department: 'tech' },
113
+ { $or: [{ level: 'senior' }, { years: { $gte: 5 } }] }
114
+ ]
115
+ }
116
+ ```
117
+
118
+ ### 复杂条件示例
119
+
120
+ ```typescript
121
+ const condition = {
122
+ status: 'active',
123
+ age: { $gte: 18, $lte: 60 },
124
+ name: { $likeInclude: '张' },
125
+ $or: [
126
+ { department: { $in: ['tech', 'product'] } },
127
+ { level: { $gte: 5 } }
128
+ ]
129
+ };
130
+ ```
131
+
132
+ ## 排序语法
133
+
134
+ ```typescript
135
+ // 标准 SQL 格式(推荐)
136
+ orderBy: 'created_at DESC'
137
+ orderBy: 'created_at DESC, amount ASC'
138
+
139
+ // 简写格式(+ 升序,- 降序)
140
+ orderBy: 'created_at-' // 降序
141
+ orderBy: 'age+' // 升序
142
+ orderBy: 'department+,age-,created_at-'
143
+
144
+ // 数组格式
145
+ orderBy: [
146
+ { fieldName: 'department', orderType: 'ASC' },
147
+ { fieldName: 'created_at', orderType: 'DESC' },
148
+ ]
149
+
150
+ // 混合数组
151
+ orderBy: [
152
+ { fieldName: 'created_at', orderType: 'DESC' },
153
+ 'amount+',
154
+ ]
155
+ ```
156
+
157
+ ## ShardingCrudPro 分表配置
158
+
159
+ ### 分表类型
160
+
161
+ | 类型 | 枚举值 | 说明 | 示例 |
162
+ |------|--------|------|------|
163
+ | 按年 | `ShardingType.YEAR` | 按年份分表 | `order_2024` |
164
+ | 按月 | `ShardingType.MONTH` | 按月份分表 | `order_202401` |
165
+ | 按日 | `ShardingType.DAY` | 按日期分表 | `order_20240101` |
166
+ | 范围 | `ShardingType.RANGE` | 按数值范围 | `user_0` ~ `user_99` |
167
+ | 哈希 | `ShardingType.HASH` | 按哈希值 | `order_01` ~ `order_16` |
168
+ | 自定义 | `ShardingType.CUSTOM` | 自定义规则 | 自定义函数决定 |
169
+
170
+ ### IShardingConfig 配置项
171
+
172
+ ```typescript
173
+ interface IShardingConfig {
174
+ type: ShardingType; // 分表类型(必填)
175
+ baseTable: string; // 基础表名(必填)
176
+
177
+ // 时间分表
178
+ timeColumn?: string; // 时间字段(时间分表必填)
179
+ recentTableCount?: number; // 无时间范围时查询最近N个分表
180
+ autoCreateTable?: boolean; // 自动创建分表(默认 false)
181
+ tableCreateOptions?: IShardingTableCreateOptions;
182
+
183
+ // 范围/哈希分表
184
+ shardingColumn?: string; // 分表字段(HASH/RANGE必填)
185
+ tableCount?: number; // 分表数量(默认 RANGE=10, HASH=16)
186
+
187
+ // COUNT 缓存(仅时间分表)
188
+ countCache?: {
189
+ ttlSeconds?: number; // 缓存有效期(默认300秒)
190
+ maxSize?: number; // 最大缓存条目(默认1000)
191
+ };
192
+
193
+ // 自定义配置
194
+ customRouter?: (ctx) => string | string[]; // 自定义路由函数
195
+ suffixFormatter?: (suffix) => string; // 自定义后缀格式化
196
+ }
197
+
198
+ interface IShardingTableCreateOptions {
199
+ copyIndexes?: boolean; // 复制原表索引
200
+ tableOptions?: string; // 表选项(如 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')
201
+ }
202
+
203
+ interface IShardingSmartBatchInsertResult {
204
+ totalAffected: number;
205
+ tableResults: Array<{ table: string; affected: number; rowCount: number }>;
206
+ tableCount: number;
207
+ success: boolean;
208
+ errors: Array<{ table: string; error: Error }>;
209
+ }
210
+ ```
211
+
212
+ ### ShardingCrudPro API
213
+
214
+ | 方法 | 参数 | 返回类型 | 说明 |
215
+ |------|------|----------|------|
216
+ | `setBaseCfg(cfg)` | `IRequestCfgModel2` | `this` | 设置基础配置 |
217
+ | `insert(reqJson)` | `IRequestModel` | `ExecuteContext` | 插入单条 |
218
+ | `batchInsert(reqJson)` | `IRequestModel` | `IShardingSmartBatchInsertResult` | 批量插入 |
219
+ | `update(reqJson)` | `IRequestModel` | `ExecuteContext` | 更新 |
220
+ | `delete(reqJson)` | `IRequestModel` | `ExecuteContext` | 删除 |
221
+ | `insertOrUpdate(reqJson)` | `IRequestModel` | `ExecuteContext` | 插入或更新 |
222
+ | `insertOnDuplicateUpdate(reqJson)` | `IRequestModel` | `ExecuteContext` | 原生 upsert |
223
+ | `queryOne(reqJson)` | `IRequestModel` | `any \| null` | 查询单条 |
224
+ | `query(reqJson)` | `IRequestModel` | `any[]` | 列表查询 |
225
+ | `queryPage(reqJson)` | `IRequestModel` | `IShardingPageQueryResult` | 分页查询 |
226
+ | `queryCount(reqJson)` | `IRequestModel` | `number` | 统计总数 |
227
+ | `isExist(reqJson)` | `IRequestModel` | `boolean` | 存在性判断 |
228
+
229
+ ## 配置模型 (IRequestCfgModel)
230
+
231
+ ```typescript
232
+ interface IRequestCfgModel {
233
+ method?: string; // 方法标识
234
+ sqlTable?: string; // 目标表名
235
+ sqlSchema?: string; // Schema(可选)
236
+ sqlDatabase?: string; // 数据库名(用于选择连接)
237
+ sqlDbType?: SqlDbType; // 'mysql' | 'postgres' | 'sqlserver'
238
+ maxLimit?: number; // 最大返回行数
239
+ columns?: string | string[]; // 选择列
240
+ columnsRelation?: ColumnRelation[]; // 数据关联配置
241
+ sqlSimpleName?: KeysOfSimpleSQL; // 简单 SQL 模式
242
+ sqlCfgList?: ISqlCfgModel[]; // 自定义 SQL 列表(高优先级)
243
+ uniqueColumn?: string[]; // 用于 insertOnDuplicate
244
+ updateCfg?: Record<string, IFuncCfgModel>; // 自动字段更新
245
+ allowCfg?: Record<string, string[]>; // 字段白名单
246
+ rejectCfg?: Record<string, string[]>; // 字段黑名单
247
+ validateCfg?: Record<string, IValidatorCfgItem[]>; // 校验规则
248
+ authType?: KeysOfAuthType; // 权限类型
249
+ authConfig?: string | string[]; // 权限配置
250
+ transactionEnable?: boolean; // 启用事务
251
+ transactionIsolation?: number; // 事务隔离级别
252
+ }
253
+
254
+ interface IRequestCfgModel2 extends IRequestCfgModel {
255
+ enableStandardUpdateCfg?: boolean | string[]; // 默认 true
256
+ enableStandardUpdateCfgCondition?: boolean | string[]; // 默认 false
257
+ enableSoftDelete?: boolean; // 软删除支持
258
+ }
259
+ ```
260
+
261
+ ### KeysOfSimpleSQL(SQL 操作类型)
262
+
263
+ | 值 | 说明 |
264
+ |----|------|
265
+ | `SIMPLE_QUERY` | SELECT 带条件,不分页 |
266
+ | `SIMPLE_QUERY_ONE` | SELECT ... LIMIT 1 |
267
+ | `SIMPLE_QUERY_PAGE` | SELECT 带分页(pageNo + pageSize)|
268
+ | `SIMPLE_QUERY_COUNT` | SELECT COUNT(*) |
269
+ | `SIMPLE_QUERY_EXIST` | SELECT EXISTS |
270
+ | `SIMPLE_INSERT` | INSERT 单行 |
271
+ | `SIMPLE_BATCH_INSERT` | INSERT 多行 |
272
+ | `SIMPLE_UPDATE` | UPDATE 带条件 |
273
+ | `SIMPLE_DELETE` | DELETE 带条件 |
274
+ | `SIMPLE_INSERT_OR_UPDATE` | 查询后插入或更新(2条 SQL)|
275
+ | `SIMPLE_INSERT_ON_DUPLICATE_UPDATE` | 原生 upsert(1条 SQL)|
276
+
277
+ ### SqlDbType
278
+
279
+ ```typescript
280
+ enum SqlDbType {
281
+ mysql = 'mysql',
282
+ postgres = 'postgres',
283
+ sqlserver = 'sqlserver',
284
+ }
285
+ ```
286
+
287
+ ### Auth Types(权限类型)
288
+
289
+ ```typescript
290
+ enum KeysOfAuthType {
291
+ free = 'free', // 无需权限
292
+ login = 'login', // 需要登录
293
+ byRoleCode = 'byRoleCode', // 角色权限
294
+ byFuncCode = 'byFuncCode', // 功能码权限
295
+ }
296
+ ```
297
+
298
+ ### Validators(校验器)
299
+
300
+ | 校验器 | 说明 |
301
+ |--------|------|
302
+ | `required` | 必填 |
303
+ | `string` | 必须是字符串 |
304
+ | `number` | 必须是数字 |
305
+ | `integer` | 必须是整数 |
306
+ | `boolean` | 必须是布尔值 |
307
+ | `email` | 邮箱格式 |
308
+ | `array` | 必须是数组 |
309
+ | `array:string` | 字符串数组 |
310
+ | `array:number` | 数字数组 |
311
+ | `phone:cn` | 中国手机号(11位)|
312
+ | `moment:FORMAT` | 日期/时间格式验证 |
313
+ | `scale:[1,3]` | 数值范围检查 |
314
+ | `length:1,5` | 字符串长度范围 |
315
+ | `regexp:[a-zA-Z]` | 正则匹配 |
316
+ | `enum:1,2,3` | 枚举值检查 |
317
+
318
+ ## 关联数据填充 (columnsRelation)
319
+
320
+ ### ColumnRelation 结构
321
+
322
+ ```typescript
323
+ interface ColumnRelation {
324
+ relatedType: 'dict' | 'sysCfgEnum' | 'accountBasic' | 'workbenchBasic' | 'linkToCustom';
325
+ relatedCode?: string; // 关联编码(dict/sysCfgEnum/linkToCustom 时必填)
326
+ sourceColumn: string; // 从结果行中取值的字段名
327
+ targetColumns?: CopyAttr[]; // 映射规则
328
+ }
329
+
330
+ interface CopyAttr {
331
+ from: string; // 关联数据中的字段名,支持 '*' 表示整体赋值
332
+ to: string; // 写入结果行的目标路径(支持嵌套,如 'user_info.name')
333
+ }
334
+ ```
335
+
336
+ ### 关联类型详解
337
+
338
+ #### dict - 数据字典
339
+
340
+ ```typescript
341
+ {
342
+ relatedType: 'dict',
343
+ relatedCode: 'SexEnum', // 字典编码
344
+ sourceColumn: 'sex', // 结果行中的 sex 字段值作为字典 value
345
+ targetColumns: [
346
+ { from: 'label', to: 'sex_text' },
347
+ { from: 'color', to: 'sex_color' },
348
+ ],
349
+ }
350
+ ```
351
+
352
+ #### sysCfgEnum - 系统配置枚举
353
+
354
+ ```typescript
355
+ {
356
+ relatedType: 'sysCfgEnum',
357
+ relatedCode: 'OrderStatus',
358
+ sourceColumn: 'order_status',
359
+ targetColumns: [
360
+ { from: 'label', to: 'order_status_info.label' },
361
+ { from: 'style', to: 'order_status_info.style' },
362
+ ],
363
+ }
364
+ ```
365
+
366
+ #### accountBasic - 用户账号信息
367
+
368
+ ```typescript
369
+ {
370
+ relatedType: 'accountBasic',
371
+ sourceColumn: 'created_by', // 用户 ID 字段
372
+ targetColumns: [], // 空数组使用默认映射
373
+ }
374
+ // 自动填充字段:created_by_nickname, created_by_avatar, created_by_account_type
375
+ ```
376
+
377
+ #### workbenchBasic - 工作台站点信息
378
+
379
+ ```typescript
380
+ {
381
+ relatedType: 'workbenchBasic',
382
+ sourceColumn: 'workbench_code',
383
+ targetColumns: [
384
+ { from: 'workbench_domain', to: 'workbench_info.workbench_domain' },
385
+ { from: 'workbench_name', to: 'workbench_info.workbench_name' },
386
+ ],
387
+ }
388
+ ```
389
+
390
+ #### linkToCustom - 自定义表关联
391
+
392
+ ```typescript
393
+ {
394
+ relatedType: 'linkToCustom',
395
+ relatedCode: 'categoryLinkConfig', // 关联配置编码(在 sys_configs 中配置)
396
+ sourceColumn: 'category_id',
397
+ targetColumns: [], // 使用配置中的默认映射
398
+ }
399
+ ```
400
+
401
+ ## 自定义 SQL 配置 (ISqlCfgModel)
402
+
403
+ ```typescript
404
+ interface ISqlCfgModel {
405
+ resName?: string; // 结果名
406
+ resPicker?: string; // 结果选择表达式
407
+ originSql?: string; // 带特殊占位符的 SQL
408
+ executeSql?: string; // 可执行 SQL(用 ? 作为参数)
409
+ executeSqlArgs?: any[]; // SQL 参数
410
+ isNativeSQL?: boolean; // 跳过框架处理
411
+ crudType?: string;
412
+ validate?: IFuncCfgModel; // 执行前校验
413
+ executeWhen?: IFuncCfgModel; // 条件执行
414
+ }
415
+ ```
416
+
417
+ ### SQL 占位符 (originSql)
418
+
419
+ | 占位符 | 说明 |
420
+ |--------|------|
421
+ | `@@columns` | 展开为列列表 |
422
+ | `@@table` | 展开为表名 |
423
+ | `@@offsetLimit` | 展开为 LIMIT/OFFSET |
424
+ | `@@orderBys` | 展开为 ORDER BY 子句 |
425
+ | `@@asWhere:fieldName` | 从字段展开为 WHERE 子句 |
426
+ | `@@asUpdate:fieldName` | 从字段展开为 SET 子句 |
427
+ | `@@asInsertKeys:fieldName` | 展开为 INSERT 列名 |
428
+ | `@@asInsertValues:fieldName` | 展开为 INSERT 值 |
429
+ | `@@asBatchInsertKeys:fieldName` | 批量 INSERT 列 |
430
+ | `@@asBatchInsertValues:fieldName` | 批量 INSERT 值 |
431
+ | `@@data.attrName` | 从 data 获取单个值 |
432
+ | `@@condition.attrName` | 从 condition 获取单个值 |
433
+ | `@@pickResAsNumber:expression` | 选择结果为数字 |
434
+ | `@@pickResAsString:expression` | 选择结果为字符串 |
435
+ | `@@function:funcName` | 执行函数 |
436
+
437
+ ## 标准表字段
438
+
439
+ 推荐业务表包含以下标准字段:
440
+
441
+ **常用字段(6个)**:`deleted_at`、`deleted_by`、`created_by`、`created_at`、`modified_by`、`modified_at`
442
+
443
+ **完整字段(12个)**:增加 `created_account_type`、`created_avatar`、`created_nickname`、`modified_account_type`、`modified_avatar`、`modified_nickname`
444
+
445
+ ### TypeScript 类型定义
446
+
447
+ ```typescript
448
+ import { StandardDataModel, FullStandardDataModel, NotDeletedCondition } from 'midway-fatcms';
449
+
450
+ interface OrderEntity {
451
+ id: number;
452
+ order_no: string;
453
+ amount: number;
454
+ }
455
+
456
+ type Order = StandardDataModel<OrderEntity>; // 自动包含 6 个标准字段
457
+ type OrderFull = FullStandardDataModel<OrderEntity>; // 自动包含 12 个标准字段
458
+
459
+ // 未删除查询条件
460
+ const condition = { ...NotDeletedCondition, status: 1 };
461
+ // 等价于 { deleted_at: 0, status: 1 }
462
+ ```
463
+
464
+ ## 响应模型
465
+
466
+ ```typescript
467
+ interface ResModelAffected {
468
+ insertId?: string | number;
469
+ affectedRows: number;
470
+ }
471
+
472
+ interface ResModelPageQuery {
473
+ rows: Record<string, any>[];
474
+ total_count: number;
475
+ }
476
+
477
+ interface ResModelStandard {
478
+ row?: Record<string, any>;
479
+ rows?: Record<string, any>[];
480
+ total_count?: number;
481
+ is_exist?: boolean;
482
+ affected?: ResModelAffected;
483
+ insert_affected?: ResModelAffected;
484
+ update_affected?: ResModelAffected;
485
+ }
486
+ ```
487
+
488
+ ## 内置函数 (IFuncCfgModel)
489
+
490
+ 在 `updateCfg` 中可用的内置函数:
491
+
492
+ ### 日期时间函数
493
+
494
+ | 函数名 | 参数 | 返回值 | 说明 |
495
+ |--------|------|--------|------|
496
+ | `getCurrentTimeStampMs` | 无 | `number` | 当前时间戳(毫秒)|
497
+ | `getCurrentTimeStampSecond` | 无 | `number` | 当前时间戳(秒)|
498
+ | `getCurrentTimeString` | 无 | `string` | 当前时间 `YYYY-MM-DD HH:mm:ss` |
499
+ | `getCurrentDateFormat` | `format: string` | `string` | 按指定格式返回当前时间 |
500
+ | `getYesterdayDateFormat` | `format: string` | `string` | 按指定格式返回昨天时间 |
501
+
502
+ ### 通用工具函数
503
+
504
+ | 函数名 | 参数 | 返回值 | 说明 |
505
+ |--------|------|--------|------|
506
+ | `uuid` | 无 | `string` | 生成 UUID v4 |
507
+ | `generateSnowflakeId` | `machineId?: number` | `string` | 生成雪花ID |
508
+ | `isNil` | `obj: any` | `boolean` | 是否为 null/undefined |
509
+ | `isNotNil` | `obj: any` | `boolean` | 不为 null 且不为 undefined |
510
+ | `isEmpty` | `obj: any` | `boolean` | 是否为空 |
511
+ | `isNotEmpty` | `obj: any` | `boolean` | 是否非空 |
512
+
513
+ ### 比较函数
514
+
515
+ | 函数名 | 参数 | 返回值 | 说明 |
516
+ |--------|------|--------|------|
517
+ | `eq` | `a, b` | `boolean` | 相等比较 |
518
+ | `ne` | `a, b` | `boolean` | 不相等 |
519
+ | `gt` | `a, b` | `boolean` | 大于 |
520
+ | `gte` | `a, b` | `boolean` | 大于等于 |
521
+ | `lt` | `a, b` | `boolean` | 小于 |
522
+ | `lte` | `a, b` | `boolean` | 小于等于 |
523
+
524
+ ### 使用示例
525
+
526
+ ```typescript
527
+ updateCfg: {
528
+ // 设置当前时间
529
+ 'data.created_at': { functionName: 'getCurrentTimeString' },
530
+
531
+ // 设置时间戳
532
+ 'data.created_ts': { functionName: 'getCurrentTimeStampMs' },
533
+
534
+ // 生成 UUID
535
+ 'data.id': { functionName: 'uuid' },
536
+
537
+ // 生成雪花ID
538
+ 'data.order_id': { functionName: 'generateSnowflakeId' },
539
+
540
+ // 带参数的函数
541
+ 'data.order_date': { functionName: 'getCurrentDateFormat', functionParams: ['YYYYMMDD'] },
542
+ }
543
+ ```
544
+
545
+ ## CurdMixService vs CurdProService 方法映射
546
+
547
+ | CurdMixService | CurdProService | 说明 |
548
+ |----------------|----------------|------|
549
+ | `executeCrudByCfg(req, cfg)` | `executeCrudByCfg(req, cfg)` | Mix 增加数据关联填充 |
550
+ | `executeCrud(req)` | `executeCrud(req)` | Mix 增加数据关联填充 |
551
+ | `getBbUtil(db, type, table)` | `getQuickCrud(db, type, table)` | 功能相同,Mix 自动准备处理器 |
552
+ | `executeSQL(sqlCfg)` | `executeSQL(sqlCfg)` | 直接 SQL 执行 |
553
+ | `getCachedCfgByMethod(m)` | `getCachedCfgByMethod(m)` | 获取缓存配置 |
554
+ | `getAllTableInfos(q, o)` | `getAllTableInfos(q, o)` | 列出数据库表 |
555
+ | `linkColumnRelationDatas(r, p)` | *(不可用)* | 为已有数据填充关联数据 |
556
+
557
+ ## 错误码参考
558
+
559
+ | 错误码 | 说明 |
560
+ |--------|------|
561
+ | `NO_AUTH` | 没有权限 |
562
+ | `NOT_LOGIN` | 未登录 |
563
+ | `CFG_NOT_FOUND` | 配置不存在 |
564
+ | `VALIDATE_EXCEPTION` | 数据校验失败 |
565
+ | `RUN_SQL_EXCEPTION_ER_DUP_ENTRY` | 数据重复 |
566
+ | `RUN_SQL_EXCEPTION_ER_NO_SUCH_TABLE` | 表不存在 |
567
+ | `RUN_FUNCTION_NOT_FOUND` | 函数未找到 |
568
+ | `SHARDING_COLUMN_MISSING` | 缺少分表字段 |