@nest-omni/core 4.1.3-10 → 4.1.3-12

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 (183) hide show
  1. package/audit/audit.module.js +42 -2
  2. package/audit/controllers/audit.controller.d.ts +64 -0
  3. package/audit/controllers/audit.controller.js +50 -0
  4. package/audit/decorators/audit-action.decorator.d.ts +74 -0
  5. package/audit/decorators/audit-action.decorator.js +42 -0
  6. package/audit/decorators/audit-controller.decorator.d.ts +1 -1
  7. package/audit/decorators/audit-controller.decorator.js +2 -2
  8. package/audit/decorators/entity-audit.decorator.d.ts +78 -2
  9. package/audit/decorators/entity-audit.decorator.js +145 -4
  10. package/audit/decorators/index.d.ts +2 -0
  11. package/audit/decorators/index.js +2 -0
  12. package/audit/entities/audit-action-summary.entity.d.ts +23 -0
  13. package/audit/entities/audit-action-summary.entity.js +101 -0
  14. package/audit/entities/entity-audit-log.entity.d.ts +8 -0
  15. package/audit/entities/entity-audit-log.entity.js +54 -2
  16. package/audit/entities/entity-transaction.entity.d.ts +8 -2
  17. package/audit/entities/entity-transaction.entity.js +39 -3
  18. package/audit/entities/index.d.ts +3 -0
  19. package/audit/entities/index.js +3 -0
  20. package/audit/entities/manual-operation-log.entity.js +8 -1
  21. package/audit/enums/audit.enums.d.ts +22 -6
  22. package/audit/enums/audit.enums.js +27 -9
  23. package/audit/index.d.ts +4 -1
  24. package/audit/index.js +25 -2
  25. package/audit/interceptors/audit-action.interceptor.d.ts +38 -0
  26. package/audit/interceptors/audit-action.interceptor.js +215 -0
  27. package/audit/interceptors/index.d.ts +1 -0
  28. package/audit/interceptors/index.js +1 -0
  29. package/audit/interfaces/audit.interfaces.d.ts +145 -2
  30. package/audit/services/audit-action.service.d.ts +141 -0
  31. package/audit/services/audit-action.service.js +244 -0
  32. package/audit/services/audit-context.service.d.ts +82 -0
  33. package/audit/services/audit-context.service.js +170 -0
  34. package/audit/services/entity-audit.service.d.ts +174 -4
  35. package/audit/services/entity-audit.service.js +515 -14
  36. package/audit/services/index.d.ts +3 -0
  37. package/audit/services/index.js +3 -0
  38. package/audit/services/manual-audit-log.service.d.ts +24 -23
  39. package/audit/services/manual-audit-log.service.js +32 -53
  40. package/audit/services/operation-description.service.d.ts +13 -3
  41. package/audit/services/operation-description.service.js +161 -24
  42. package/audit/services/transaction-audit.service.js +3 -3
  43. package/audit/subscribers/entity-audit.subscriber.d.ts +4 -0
  44. package/audit/subscribers/entity-audit.subscriber.js +47 -0
  45. package/file-upload/controllers/file-access.controller.d.ts +23 -0
  46. package/file-upload/controllers/file-access.controller.js +128 -0
  47. package/file-upload/decorators/csv-data.decorator.d.ts +44 -0
  48. package/file-upload/decorators/csv-data.decorator.js +131 -0
  49. package/file-upload/decorators/excel-data.decorator.d.ts +44 -0
  50. package/file-upload/decorators/excel-data.decorator.js +125 -0
  51. package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
  52. package/file-upload/decorators/file-upload.decorator.js +172 -0
  53. package/file-upload/decorators/index.d.ts +4 -0
  54. package/file-upload/decorators/index.js +20 -0
  55. package/file-upload/decorators/process.decorator.d.ts +40 -0
  56. package/file-upload/decorators/process.decorator.js +52 -0
  57. package/file-upload/dto/create-file.dto.d.ts +24 -0
  58. package/file-upload/dto/create-file.dto.js +112 -0
  59. package/file-upload/dto/find-files.dto.d.ts +15 -0
  60. package/file-upload/dto/find-files.dto.js +76 -0
  61. package/file-upload/dto/index.d.ts +4 -0
  62. package/file-upload/dto/index.js +20 -0
  63. package/file-upload/dto/pagination.dto.d.ts +7 -0
  64. package/file-upload/dto/pagination.dto.js +39 -0
  65. package/file-upload/dto/update-file.dto.d.ts +16 -0
  66. package/file-upload/dto/update-file.dto.js +71 -0
  67. package/file-upload/entities/file-metadata.entity.d.ts +22 -0
  68. package/file-upload/entities/file-metadata.entity.js +84 -0
  69. package/file-upload/entities/file.entity.d.ts +129 -0
  70. package/file-upload/entities/file.entity.js +384 -0
  71. package/file-upload/entities/index.d.ts +2 -0
  72. package/file-upload/entities/index.js +18 -0
  73. package/file-upload/enums/file-type.enum.d.ts +72 -0
  74. package/file-upload/enums/file-type.enum.js +212 -0
  75. package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
  76. package/file-upload/exceptions/file-upload.exception.js +120 -0
  77. package/file-upload/exceptions/index.d.ts +1 -0
  78. package/file-upload/exceptions/index.js +17 -0
  79. package/file-upload/file-upload.module.d.ts +89 -0
  80. package/file-upload/file-upload.module.js +264 -0
  81. package/file-upload/index.d.ts +26 -0
  82. package/file-upload/index.js +59 -0
  83. package/file-upload/interceptors/file-upload.interceptor.d.ts +48 -0
  84. package/file-upload/interceptors/file-upload.interceptor.js +434 -0
  85. package/file-upload/interceptors/index.d.ts +1 -0
  86. package/file-upload/interceptors/index.js +17 -0
  87. package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
  88. package/file-upload/interfaces/custom-file-type.interface.js +2 -0
  89. package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
  90. package/file-upload/interfaces/file-buffer.interface.js +2 -0
  91. package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
  92. package/file-upload/interfaces/file-entity.interface.js +28 -0
  93. package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
  94. package/file-upload/interfaces/file-metadata.interface.js +2 -0
  95. package/file-upload/interfaces/file-upload-options.interface.d.ts +117 -0
  96. package/file-upload/interfaces/file-upload-options.interface.js +2 -0
  97. package/file-upload/interfaces/index.d.ts +7 -0
  98. package/file-upload/interfaces/index.js +24 -0
  99. package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
  100. package/file-upload/interfaces/storage-provider.interface.js +2 -0
  101. package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
  102. package/file-upload/interfaces/upload-options.interface.js +2 -0
  103. package/file-upload/providers/index.d.ts +2 -0
  104. package/file-upload/providers/index.js +18 -0
  105. package/file-upload/providers/local-storage.provider.d.ts +98 -0
  106. package/file-upload/providers/local-storage.provider.js +484 -0
  107. package/file-upload/providers/s3-storage.provider.d.ts +87 -0
  108. package/file-upload/providers/s3-storage.provider.js +455 -0
  109. package/file-upload/services/file-signature-validator.service.d.ts +118 -0
  110. package/file-upload/services/file-signature-validator.service.js +376 -0
  111. package/file-upload/services/file.service.d.ts +190 -0
  112. package/file-upload/services/file.service.js +609 -0
  113. package/file-upload/services/index.d.ts +4 -0
  114. package/file-upload/services/index.js +20 -0
  115. package/file-upload/services/malicious-file-detector.service.d.ts +274 -0
  116. package/file-upload/services/malicious-file-detector.service.js +1035 -0
  117. package/file-upload/services/mime-registry.service.d.ts +47 -0
  118. package/file-upload/services/mime-registry.service.js +167 -0
  119. package/file-upload/utils/checksum.util.d.ts +28 -0
  120. package/file-upload/utils/checksum.util.js +65 -0
  121. package/file-upload/utils/dynamic-import.util.d.ts +50 -0
  122. package/file-upload/utils/dynamic-import.util.js +144 -0
  123. package/file-upload/utils/filename.util.d.ts +59 -0
  124. package/file-upload/utils/filename.util.js +184 -0
  125. package/file-upload/utils/filepath.util.d.ts +70 -0
  126. package/file-upload/utils/filepath.util.js +152 -0
  127. package/file-upload/utils/index.d.ts +4 -0
  128. package/file-upload/utils/index.js +20 -0
  129. package/http-client/http-client.module.js +1 -5
  130. package/index.d.ts +3 -1
  131. package/index.js +4 -1
  132. package/package.json +4 -5
  133. package/redis-lock/lock-heartbeat.service.d.ts +2 -2
  134. package/redis-lock/lock-heartbeat.service.js +4 -4
  135. package/redis-lock/redis-lock.service.d.ts +18 -0
  136. package/redis-lock/redis-lock.service.js +38 -8
  137. package/setup/bootstrap.setup.d.ts +1 -0
  138. package/setup/bootstrap.setup.js +1 -0
  139. package/setup/schedule.decorator.js +18 -8
  140. package/shared/index.d.ts +1 -1
  141. package/shared/index.js +1 -1
  142. package/shared/{serviceRegistryModule.js → service-registry.module.js} +9 -16
  143. package/shared/services/index.d.ts +0 -1
  144. package/shared/services/index.js +0 -1
  145. package/transaction/__tests__/mocks.d.ts +9 -0
  146. package/transaction/__tests__/mocks.js +33 -0
  147. package/transaction/base-service-transaction.d.ts +99 -0
  148. package/transaction/base-service-transaction.js +286 -0
  149. package/transaction/cls-compatibility.service.d.ts +55 -0
  150. package/transaction/cls-compatibility.service.js +127 -0
  151. package/transaction/data-source-registry.d.ts +91 -0
  152. package/transaction/data-source-registry.js +349 -0
  153. package/transaction/database-adapter.d.ts +44 -0
  154. package/transaction/database-adapter.js +240 -0
  155. package/transaction/decorators/entity-datasource.decorator.d.ts +62 -0
  156. package/transaction/decorators/entity-datasource.decorator.js +105 -0
  157. package/transaction/index.d.ts +14 -0
  158. package/transaction/index.js +57 -0
  159. package/transaction/logging-transactional.interceptor.d.ts +18 -0
  160. package/transaction/logging-transactional.interceptor.js +163 -0
  161. package/transaction/transaction-context.service.d.ts +137 -0
  162. package/transaction/transaction-context.service.js +411 -0
  163. package/transaction/transaction-manager.d.ts +230 -0
  164. package/transaction/transaction-manager.js +1001 -0
  165. package/transaction/transaction-synchronization.d.ts +171 -0
  166. package/transaction/transaction-synchronization.js +380 -0
  167. package/transaction/transaction.errors.d.ts +91 -0
  168. package/transaction/transaction.errors.js +206 -0
  169. package/transaction/transaction.module.d.ts +30 -0
  170. package/transaction/transaction.module.js +98 -0
  171. package/transaction/transactional.decorator.d.ts +82 -0
  172. package/transaction/transactional.decorator.js +319 -0
  173. package/transaction/typeorm-module-wrapper.d.ts +96 -0
  174. package/transaction/typeorm-module-wrapper.js +197 -0
  175. package/validators/file-mimetype.validator.d.ts +0 -2
  176. package/validators/file-mimetype.validator.js +4 -6
  177. package/validators/is-exists.validator.d.ts +2 -5
  178. package/validators/is-exists.validator.js +4 -6
  179. package/validators/is-unique.validator.d.ts +2 -5
  180. package/validators/is-unique.validator.js +6 -11
  181. package/shared/services/validator.service.d.ts +0 -3
  182. package/shared/services/validator.service.js +0 -20
  183. /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.AuditActionService = void 0;
22
+ const common_1 = require("@nestjs/common");
23
+ const audit_context_service_1 = require("./audit-context.service");
24
+ const entity_audit_service_1 = require("./entity-audit.service");
25
+ const enums_1 = require("../enums");
26
+ /**
27
+ * 审计动作服务
28
+ * 提供声明式的审计动作管理,自动关联同一业务操作的所有实体变化
29
+ */
30
+ let AuditActionService = class AuditActionService {
31
+ constructor(contextService, auditService) {
32
+ this.contextService = contextService;
33
+ this.auditService = auditService;
34
+ }
35
+ /**
36
+ * 在审计动作上下文中执行操作
37
+ * 自动关联该动作内的所有实体变化
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const result = await auditActionService.executeAction(
42
+ * {
43
+ * actionName: 'createOrder',
44
+ * operationTemplateKey: 'order.create',
45
+ * descriptionParams: {
46
+ * productCount: orderItems.length,
47
+ * receiver: order.receiverName,
48
+ * totalAmount: order.totalAmount,
49
+ * address: order.shippingAddress,
50
+ * },
51
+ * },
52
+ * async () => {
53
+ * // 1. 创建订单
54
+ * const order = await this.orderRepository.save(newOrder);
55
+ *
56
+ * // 2. 创建订单项
57
+ * await this.orderItemRepository.save(orderItems);
58
+ *
59
+ * // 3. 扣减库存
60
+ * await this.inventoryService.deduct(orderItems);
61
+ *
62
+ * // 4. 创建物流信息
63
+ * await this.shippingService.create(order.id);
64
+ *
65
+ * return order;
66
+ * }
67
+ * );
68
+ *
69
+ * // 结果中包含所有实体变化:
70
+ * // result.entityChanges = [
71
+ * // { entityType: 'Order', entityId: '1', operation: 'CREATE', sequence: 1 },
72
+ * // { entityType: 'OrderItem', entityId: '1', operation: 'CREATE', sequence: 2 },
73
+ * // { entityType: 'OrderItem', entityId: '2', operation: 'CREATE', sequence: 3 },
74
+ * // { entityType: 'Inventory', entityId: '1', operation: 'UPDATE', sequence: 4 },
75
+ * // { entityType: 'Shipping', entityId: '1', operation: 'CREATE', sequence: 5 },
76
+ * // ]
77
+ * ```
78
+ */
79
+ executeAction(options, operation) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ const actionId = this.contextService.generateActionId();
82
+ const startTime = new Date();
83
+ // 创建审计动作上下文
84
+ const actionContext = {
85
+ actionId,
86
+ actionName: options.actionName,
87
+ operationTemplateKey: options.operationTemplateKey,
88
+ descriptionParams: options.descriptionParams,
89
+ startTime,
90
+ entityChanges: [],
91
+ detailedChanges: [],
92
+ };
93
+ // 设置到 CLS
94
+ this.contextService.setActionContext(actionContext);
95
+ let success = false;
96
+ let error;
97
+ let result;
98
+ try {
99
+ // 执行业务操作
100
+ result = yield operation();
101
+ success = true;
102
+ // 记录审计动作汇总日志(可选)
103
+ yield this.recordActionSummary(actionContext, options);
104
+ return {
105
+ actionId,
106
+ actionName: options.actionName,
107
+ entityChanges: actionContext.entityChanges,
108
+ duration: Date.now() - startTime.getTime(),
109
+ success: true,
110
+ };
111
+ }
112
+ catch (err) {
113
+ error = err;
114
+ success = false;
115
+ // 记录失败的审计动作
116
+ yield this.recordActionSummary(actionContext, options, error);
117
+ throw err;
118
+ }
119
+ finally {
120
+ // 清除审计动作上下文
121
+ this.contextService.clearActionContext();
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * 记录审计动作汇总日志
127
+ */
128
+ recordActionSummary(actionContext, options, error) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ try {
131
+ const context = yield this.contextService.getCurrentContext();
132
+ // 使用 logEntityChangeWithTemplate 记录汇总信息
133
+ yield this.auditService.logEntityChangeWithTemplate({
134
+ entityType: 'AuditAction',
135
+ entityId: actionContext.actionId,
136
+ operation: error ? enums_1.AuditOperation.DELETE : enums_1.AuditOperation.CREATE, // 失败用 DELETE 表示回滚
137
+ oldValue: {},
138
+ newValue: {
139
+ actionName: actionContext.actionName,
140
+ entityChangesCount: actionContext.entityChanges.length,
141
+ duration: Date.now() - actionContext.startTime.getTime(),
142
+ success: !error,
143
+ error: error === null || error === void 0 ? void 0 : error.message,
144
+ },
145
+ operationTemplateKey: options.operationTemplateKey,
146
+ descriptionParams: options.descriptionParams,
147
+ metadata: Object.assign(Object.assign({}, options.metadata), { auditActionId: actionContext.actionId, entityChanges: actionContext.entityChanges }),
148
+ });
149
+ }
150
+ catch (err) {
151
+ console.error('Failed to record audit action summary:', err);
152
+ }
153
+ });
154
+ }
155
+ /**
156
+ * 获取审计动作的所有实体变化
157
+ */
158
+ getActionAuditLogs(actionId) {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ const logs = yield this.auditService['auditLogRepository'].find({
161
+ where: { auditActionId: actionId },
162
+ order: { sequenceInAction: 'ASC', createdAt: 'ASC' },
163
+ });
164
+ return {
165
+ actionId,
166
+ logs,
167
+ summary: {
168
+ totalChanges: logs.length,
169
+ operations: this.groupByOperation(logs),
170
+ entities: this.groupByEntity(logs),
171
+ },
172
+ };
173
+ });
174
+ }
175
+ /**
176
+ * 获取请求内的所有审计动作
177
+ */
178
+ getRequestActions(requestId) {
179
+ return __awaiter(this, void 0, void 0, function* () {
180
+ const logs = yield this.auditService['auditLogRepository'].find({
181
+ where: { requestId },
182
+ order: { createdAt: 'ASC' },
183
+ });
184
+ // 按 auditActionId 分组
185
+ const actionMap = new Map();
186
+ const noActionLogs = [];
187
+ logs.forEach(log => {
188
+ if (log.auditActionId) {
189
+ if (!actionMap.has(log.auditActionId)) {
190
+ actionMap.set(log.auditActionId, []);
191
+ }
192
+ actionMap.get(log.auditActionId).push(log);
193
+ }
194
+ else {
195
+ noActionLogs.push(log);
196
+ }
197
+ });
198
+ const actions = Array.from(actionMap.entries()).map(([actionId, logs]) => {
199
+ var _a;
200
+ return ({
201
+ actionId,
202
+ actionName: ((_a = logs[0]) === null || _a === void 0 ? void 0 : _a.auditActionName) || 'Unknown',
203
+ entityChanges: logs.map(log => ({
204
+ entityType: log.entityType,
205
+ entityId: log.entityId,
206
+ operation: log.operation,
207
+ sequence: log.sequenceInAction,
208
+ timestamp: log.createdAt,
209
+ })),
210
+ logs,
211
+ });
212
+ });
213
+ return {
214
+ requestId,
215
+ actions,
216
+ noActionLogs, // 未关联到任何动作的日志
217
+ summary: {
218
+ totalActions: actions.length,
219
+ totalChanges: logs.length,
220
+ },
221
+ };
222
+ });
223
+ }
224
+ groupByOperation(logs) {
225
+ const result = new Map();
226
+ logs.forEach(log => {
227
+ result.set(log.operation, (result.get(log.operation) || 0) + 1);
228
+ });
229
+ return Object.fromEntries(result);
230
+ }
231
+ groupByEntity(logs) {
232
+ const result = new Map();
233
+ logs.forEach(log => {
234
+ result.set(log.entityType, (result.get(log.entityType) || 0) + 1);
235
+ });
236
+ return Object.fromEntries(result);
237
+ }
238
+ };
239
+ exports.AuditActionService = AuditActionService;
240
+ exports.AuditActionService = AuditActionService = __decorate([
241
+ (0, common_1.Injectable)(),
242
+ __metadata("design:paramtypes", [audit_context_service_1.AuditContextService,
243
+ entity_audit_service_1.EntityAuditService])
244
+ ], AuditActionService);
@@ -1,5 +1,55 @@
1
1
  import { ClsService } from 'nestjs-cls';
2
2
  import { AuditContext } from '../interfaces';
3
+ import { AuditOperation } from '../enums';
4
+ /**
5
+ * 实体变更详情
6
+ */
7
+ export interface EntityChangeDetail {
8
+ entityType: string;
9
+ entityId: string;
10
+ operation: AuditOperation;
11
+ oldValue: Record<string, any>;
12
+ newValue: Record<string, any>;
13
+ changedFields: string[];
14
+ sequence: number;
15
+ metadata?: Record<string, any>;
16
+ }
17
+ /**
18
+ * 审计参数上下文
19
+ */
20
+ export interface AuditParamsContext {
21
+ req: any;
22
+ result?: any;
23
+ error?: Error;
24
+ entityChanges: EntityChangeDetail[];
25
+ findEntity(entityType: string, operation?: AuditOperation): EntityChangeDetail | null;
26
+ findEntities(entityType: string, operation?: AuditOperation): EntityChangeDetail[];
27
+ countEntities(entityType: string, operation?: AuditOperation): number;
28
+ extractParams(mapping: Record<string, any>): Record<string, any>;
29
+ extractByPath(path: string): any;
30
+ extractByConfig(config: any): any;
31
+ }
32
+ /**
33
+ * 审计动作上下文
34
+ */
35
+ export interface AuditActionContext {
36
+ actionId: string;
37
+ actionName: string;
38
+ operationTemplateKey?: string;
39
+ descriptionParams?: Record<string, any>;
40
+ paramsBuilder?: (context: AuditParamsContext) => Record<string, any>;
41
+ startTime: Date;
42
+ entityChanges: Array<{
43
+ entityType: string;
44
+ entityId: string;
45
+ operation: string;
46
+ sequence: number;
47
+ }>;
48
+ detailedChanges: EntityChangeDetail[];
49
+ req?: any;
50
+ result?: any;
51
+ error?: Error;
52
+ }
3
53
  /**
4
54
  * 审计上下文服务
5
55
  */
@@ -22,4 +72,36 @@ export declare class AuditContextService {
22
72
  * 获取默认上下文
23
73
  */
24
74
  private getDefaultContext;
75
+ /**
76
+ * 获取当前审计动作上下文
77
+ */
78
+ getCurrentActionContext(): AuditActionContext | null;
79
+ /**
80
+ * 设置审计动作上下文
81
+ */
82
+ setActionContext(context: AuditActionContext): void;
83
+ /**
84
+ * 清除审计动作上下文
85
+ */
86
+ clearActionContext(): void;
87
+ /**
88
+ * 记录实体变化到当前动作(简单版本)
89
+ */
90
+ recordEntityChangeInAction(entityType: string, entityId: string, operation: string): void;
91
+ /**
92
+ * 记录详细的实体变化
93
+ */
94
+ recordDetailedEntityChange(entityType: string, entityId: string, operation: AuditOperation, oldValue: Record<string, any>, newValue: Record<string, any>, changedFields: string[], metadata?: Record<string, any>): void;
95
+ /**
96
+ * 获取当前动作内的序号
97
+ */
98
+ getSequenceInAction(): number;
99
+ /**
100
+ * 生成审计动作ID
101
+ */
102
+ generateActionId(): string;
103
+ /**
104
+ * 构建审计参数上下文
105
+ */
106
+ buildParamsContext(): AuditParamsContext | null;
25
107
  }
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.AuditContextService = void 0;
22
22
  const common_1 = require("@nestjs/common");
23
23
  const nestjs_cls_1 = require("nestjs-cls");
24
+ const crypto_1 = require("crypto");
24
25
  /**
25
26
  * 审计上下文服务
26
27
  */
@@ -62,6 +63,175 @@ let AuditContextService = class AuditContextService {
62
63
  timestamp: new Date(),
63
64
  };
64
65
  }
66
+ // ========== 审计动作上下文管理 ==========
67
+ /**
68
+ * 获取当前审计动作上下文
69
+ */
70
+ getCurrentActionContext() {
71
+ return this.cls.get('auditActionContext') || null;
72
+ }
73
+ /**
74
+ * 设置审计动作上下文
75
+ */
76
+ setActionContext(context) {
77
+ this.cls.set('auditActionContext', context);
78
+ }
79
+ /**
80
+ * 清除审计动作上下文
81
+ */
82
+ clearActionContext() {
83
+ this.cls.set('auditActionContext', null);
84
+ }
85
+ /**
86
+ * 记录实体变化到当前动作(简单版本)
87
+ */
88
+ recordEntityChangeInAction(entityType, entityId, operation) {
89
+ const actionContext = this.getCurrentActionContext();
90
+ if (actionContext) {
91
+ actionContext.entityChanges.push({
92
+ entityType,
93
+ entityId,
94
+ operation,
95
+ sequence: actionContext.entityChanges.length + 1,
96
+ });
97
+ }
98
+ }
99
+ /**
100
+ * 记录详细的实体变化
101
+ */
102
+ recordDetailedEntityChange(entityType, entityId, operation, oldValue, newValue, changedFields, metadata) {
103
+ const actionContext = this.getCurrentActionContext();
104
+ if (actionContext) {
105
+ const detail = {
106
+ entityType,
107
+ entityId,
108
+ operation,
109
+ oldValue,
110
+ newValue,
111
+ changedFields,
112
+ sequence: actionContext.detailedChanges.length + 1,
113
+ metadata,
114
+ };
115
+ actionContext.detailedChanges.push(detail);
116
+ }
117
+ }
118
+ /**
119
+ * 获取当前动作内的序号
120
+ */
121
+ getSequenceInAction() {
122
+ const actionContext = this.getCurrentActionContext();
123
+ return actionContext ? actionContext.entityChanges.length + 1 : 0;
124
+ }
125
+ /**
126
+ * 生成审计动作ID
127
+ */
128
+ generateActionId() {
129
+ return (0, crypto_1.randomBytes)(16).toString('hex');
130
+ }
131
+ /**
132
+ * 构建审计参数上下文
133
+ */
134
+ buildParamsContext() {
135
+ const actionContext = this.getCurrentActionContext();
136
+ if (!actionContext) {
137
+ return null;
138
+ }
139
+ const context = {
140
+ req: actionContext.req,
141
+ result: actionContext.result,
142
+ error: actionContext.error,
143
+ entityChanges: actionContext.detailedChanges,
144
+ // 查找单个实体
145
+ findEntity(entityType, operation) {
146
+ return context.entityChanges.find((change) => change.entityType === entityType &&
147
+ (operation === undefined || change.operation === operation)) || null;
148
+ },
149
+ // 查找多个实体
150
+ findEntities(entityType, operation) {
151
+ return context.entityChanges.filter((change) => change.entityType === entityType &&
152
+ (operation === undefined || change.operation === operation));
153
+ },
154
+ // 统计实体数量
155
+ countEntities(entityType, operation) {
156
+ return context.findEntities(entityType, operation).length;
157
+ },
158
+ // 路径提取
159
+ extractParams(mapping) {
160
+ const result = {};
161
+ for (const [key, value] of Object.entries(mapping)) {
162
+ if (typeof value === 'string') {
163
+ // 简单路径: 'Order.CREATE.orderSn'
164
+ result[key] = this.extractByPath(value);
165
+ }
166
+ else if (typeof value === 'object' && value.type) {
167
+ // 复杂提取: { type: 'join', path: 'OrderItem.CREATE', field: 'name' }
168
+ result[key] = this.extractByConfig(value);
169
+ }
170
+ }
171
+ return result;
172
+ },
173
+ extractByPath(path) {
174
+ const parts = path.split('.');
175
+ if (parts.length < 2)
176
+ return undefined;
177
+ const [entityType, operationStr, ...fieldParts] = parts;
178
+ const operation = operationStr;
179
+ const entity = context.findEntity(entityType, operation);
180
+ if (!entity)
181
+ return undefined;
182
+ // 支持嵌套字段访问
183
+ let value = entity.newValue;
184
+ for (const field of fieldParts) {
185
+ if (value && typeof value === 'object') {
186
+ value = value[field];
187
+ }
188
+ else {
189
+ return undefined;
190
+ }
191
+ }
192
+ return value;
193
+ },
194
+ extractByConfig(config) {
195
+ const { type, path, field, separator = ', ' } = config;
196
+ const parts = path.split('.');
197
+ const [entityType, operationStr] = parts;
198
+ const operation = operationStr;
199
+ const entities = context.findEntities(entityType, operation);
200
+ switch (type) {
201
+ case 'count':
202
+ return entities.length;
203
+ case 'join': {
204
+ const values = entities.map((e) => {
205
+ const fieldParts = field.split('.');
206
+ let value = e.newValue;
207
+ for (const part of fieldParts) {
208
+ if (part === 'metadata') {
209
+ value = e.metadata;
210
+ }
211
+ else if (value && typeof value === 'object') {
212
+ value = value[part];
213
+ }
214
+ else {
215
+ return undefined;
216
+ }
217
+ }
218
+ return value;
219
+ }).filter(Boolean);
220
+ return values.join(separator);
221
+ }
222
+ case 'sum': {
223
+ return entities.reduce((sum, e) => {
224
+ const value = e.newValue[field];
225
+ return sum + (typeof value === 'number' ? value : 0);
226
+ }, 0);
227
+ }
228
+ default:
229
+ return undefined;
230
+ }
231
+ },
232
+ };
233
+ return context;
234
+ }
65
235
  };
66
236
  exports.AuditContextService = AuditContextService;
67
237
  exports.AuditContextService = AuditContextService = __decorate([