@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,215 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.AuditActionInterceptor = void 0;
25
+ const common_1 = require("@nestjs/common");
26
+ const core_1 = require("@nestjs/core");
27
+ const rxjs_1 = require("rxjs");
28
+ const operators_1 = require("rxjs/operators");
29
+ const typeorm_1 = require("@nestjs/typeorm");
30
+ const typeorm_2 = require("typeorm");
31
+ const audit_context_service_1 = require("../services/audit-context.service");
32
+ const operation_description_service_1 = require("../services/operation-description.service");
33
+ const entities_1 = require("../entities");
34
+ const audit_action_decorator_1 = require("../decorators/audit-action.decorator");
35
+ /**
36
+ * 审计动作拦截器
37
+ * 在请求开始时创建审计动作上下文,在请求结束时生成汇总记录
38
+ */
39
+ let AuditActionInterceptor = class AuditActionInterceptor {
40
+ constructor(reflector, contextService, summaryRepository, descriptionService) {
41
+ this.reflector = reflector;
42
+ this.contextService = contextService;
43
+ this.summaryRepository = summaryRepository;
44
+ this.descriptionService = descriptionService;
45
+ }
46
+ intercept(context, next) {
47
+ // 获取装饰器元数据
48
+ const metadata = this.reflector.get(audit_action_decorator_1.AUDIT_ACTION_METADATA, context.getHandler());
49
+ // 如果没有 @AuditAction 装饰器或已禁用,直接放行
50
+ if (!metadata || metadata.options.enabled === false) {
51
+ return next.handle();
52
+ }
53
+ const request = context.switchToHttp().getRequest();
54
+ const actionId = this.contextService.generateActionId();
55
+ const startTime = new Date();
56
+ // 创建审计动作上下文
57
+ const actionContext = {
58
+ actionId,
59
+ actionName: metadata.actionName,
60
+ operationTemplateKey: metadata.options.templateKey,
61
+ paramsBuilder: metadata.options.paramsBuilder,
62
+ startTime,
63
+ entityChanges: [],
64
+ detailedChanges: [],
65
+ req: request,
66
+ };
67
+ // 设置到 CLS
68
+ this.contextService.setActionContext(actionContext);
69
+ return next.handle().pipe((0, operators_1.tap)((result) => __awaiter(this, void 0, void 0, function* () {
70
+ // 请求成功,记录结果
71
+ actionContext.result = result;
72
+ yield this.generateSummary(actionContext, metadata, false);
73
+ })), (0, operators_1.catchError)((error) => __awaiter(this, void 0, void 0, function* () {
74
+ // 请求失败,记录错误
75
+ actionContext.error = error;
76
+ yield this.generateSummary(actionContext, metadata, true, error);
77
+ return (0, rxjs_1.throwError)(() => error);
78
+ })));
79
+ }
80
+ /**
81
+ * 生成审计汇总记录
82
+ */
83
+ generateSummary(actionContext, metadata, hasError, error) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ try {
86
+ const duration = Date.now() - actionContext.startTime.getTime();
87
+ const auditContext = yield this.contextService.getCurrentContext();
88
+ // 构建描述参数
89
+ let descriptionParams = {};
90
+ if (metadata.options.paramsBuilder) {
91
+ const paramsContext = this.contextService.buildParamsContext();
92
+ if (paramsContext) {
93
+ descriptionParams = metadata.options.paramsBuilder(paramsContext);
94
+ }
95
+ }
96
+ // 生成描述文本
97
+ const description = yield this.generateDescription(actionContext.operationTemplateKey, actionContext.actionName, descriptionParams, !hasError);
98
+ // 统计实体类型和操作
99
+ const entityTypes = Array.from(new Set(actionContext.detailedChanges.map((c) => c.entityType)));
100
+ const operationStats = {};
101
+ actionContext.detailedChanges.forEach((change) => {
102
+ const op = change.operation;
103
+ operationStats[op] = (operationStats[op] || 0) + 1;
104
+ });
105
+ // 创建汇总记录
106
+ const summary = this.summaryRepository.create({
107
+ id: actionContext.actionId,
108
+ actionName: actionContext.actionName,
109
+ operationTemplateKey: actionContext.operationTemplateKey,
110
+ descriptionParams,
111
+ description,
112
+ requestId: auditContext.requestId || '',
113
+ userId: auditContext.userId || '',
114
+ username: auditContext.username || '',
115
+ requestIp: auditContext.requestIp || '',
116
+ userAgent: auditContext.userAgent || '',
117
+ entityChangesCount: actionContext.detailedChanges.length,
118
+ entityTypes,
119
+ operationStats,
120
+ success: !hasError,
121
+ errorMessage: error === null || error === void 0 ? void 0 : error.message,
122
+ duration,
123
+ metadata: metadata.options.metadata,
124
+ });
125
+ yield this.summaryRepository.save(summary);
126
+ }
127
+ catch (err) {
128
+ console.error('Failed to generate audit action summary:', err);
129
+ }
130
+ finally {
131
+ // 清除审计动作上下文
132
+ this.contextService.clearActionContext();
133
+ }
134
+ });
135
+ }
136
+ /**
137
+ * 生成操作描述文本
138
+ * 优先从 OperationDescriptionService 获取多语言模板
139
+ * 如果没有,则使用默认格式
140
+ */
141
+ generateDescription(templateKey, actionName, params, success) {
142
+ return __awaiter(this, void 0, void 0, function* () {
143
+ let template;
144
+ // 1. 尝试从模板服务获取模板
145
+ if (templateKey && this.descriptionService) {
146
+ try {
147
+ template = yield this.descriptionService.getTemplate(templateKey);
148
+ }
149
+ catch (error) {
150
+ // 如果获取模板失败,继续使用默认逻辑
151
+ }
152
+ }
153
+ // 2. 如果没有模板,使用默认格式
154
+ if (!template) {
155
+ template = success
156
+ ? `执行操作: ${actionName}`
157
+ : `执行操作失败: ${actionName}`;
158
+ }
159
+ // 3. 执行模板替换
160
+ return this.replaceTemplatePlaceholders(template, params);
161
+ });
162
+ }
163
+ /**
164
+ * 替换模板中的占位符
165
+ * 支持格式:{key} 或 {key:format}
166
+ */
167
+ replaceTemplatePlaceholders(template, params) {
168
+ let result = template;
169
+ // 遍历所有参数,替换占位符
170
+ Object.entries(params).forEach(([key, value]) => {
171
+ const placeholder = `{${key}}`;
172
+ const valueStr = this.formatValue(value);
173
+ // 替换所有匹配的占位符
174
+ const regex = new RegExp(placeholder.replace(/[{}]/g, '\\$&'), 'g');
175
+ result = result.replace(regex, valueStr);
176
+ });
177
+ // 清理未替换的占位符
178
+ result = result.replace(/\{[^}]+\}/g, '');
179
+ return result;
180
+ }
181
+ /**
182
+ * 格式化值为字符串
183
+ */
184
+ formatValue(value) {
185
+ if (value === null || value === undefined) {
186
+ return '';
187
+ }
188
+ if (Array.isArray(value)) {
189
+ // 处理数组
190
+ if (value.length === 0) {
191
+ return '';
192
+ }
193
+ // 如果是对象数组,序列化
194
+ if (typeof value[0] === 'object') {
195
+ return JSON.stringify(value);
196
+ }
197
+ // 否则用顿号连接
198
+ return value.join('、');
199
+ }
200
+ if (typeof value === 'object') {
201
+ return JSON.stringify(value);
202
+ }
203
+ return String(value);
204
+ }
205
+ };
206
+ exports.AuditActionInterceptor = AuditActionInterceptor;
207
+ exports.AuditActionInterceptor = AuditActionInterceptor = __decorate([
208
+ (0, common_1.Injectable)(),
209
+ __param(2, (0, common_1.Inject)((0, typeorm_1.getRepositoryToken)(entities_1.AuditActionSummaryEntity))),
210
+ __param(3, (0, common_1.Optional)()),
211
+ __metadata("design:paramtypes", [core_1.Reflector,
212
+ audit_context_service_1.AuditContextService,
213
+ typeorm_2.Repository,
214
+ operation_description_service_1.OperationDescriptionService])
215
+ ], AuditActionInterceptor);
@@ -1 +1,2 @@
1
1
  export * from './audit.interceptor';
2
+ export * from './audit-action.interceptor';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./audit.interceptor"), exports);
18
+ __exportStar(require("./audit-action.interceptor"), exports);
@@ -1,4 +1,4 @@
1
- import { AuditOperation, MaskingStrategy, RecordStrategy } from '../enums/audit.enums';
1
+ import { AuditOperation, MaskingStrategy, RecordStrategy, RollbackActionType, ChangeType } from '../enums/audit.enums';
2
2
  /**
3
3
  * 审计上下文
4
4
  */
@@ -124,12 +124,43 @@ export interface AuditConfig {
124
124
  /**
125
125
  * 实体级别审计配置
126
126
  */
127
+ /**
128
+ * 实体审计配置
129
+ *
130
+ * @description
131
+ * 支持基础审计配置
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * @EntityAudit({
136
+ * enabled: true,
137
+ * excludeFields: ['password'],
138
+ * maskFields: ['email', 'phone'],
139
+ * templateKey: 'user',
140
+ * })
141
+ * ```
142
+ */
127
143
  export interface EntityAuditConfig {
128
144
  enabled?: boolean;
129
145
  strategy?: RecordStrategy;
130
146
  includeFields?: string[];
131
147
  excludeFields?: string[];
132
148
  maskFields?: string[];
149
+ /**
150
+ * 实体标签(支持多语言)
151
+ * @example
152
+ * // 单语言
153
+ * label: '订单'
154
+ *
155
+ * // 多语言
156
+ * label: { zh: '订单', en: 'Order', ja: '注文' }
157
+ */
158
+ label?: string | Record<string, string>;
159
+ /**
160
+ * 操作模板键前缀
161
+ * @example 'user' -> 生成 'user.create', 'user.update', 'user.delete'
162
+ */
163
+ templateKey?: string;
133
164
  }
134
165
  /**
135
166
  * 操作级别审计配置
@@ -142,7 +173,25 @@ export interface OperationAuditConfig {
142
173
  * 字段显示选项
143
174
  */
144
175
  export interface FieldDisplayOptions {
145
- displayName?: string;
176
+ /**
177
+ * 字段标签(支持多语言)
178
+ * @example
179
+ * // 单语言
180
+ * label: '姓名'
181
+ *
182
+ * // 多语言
183
+ * label: { zh: '姓名', en: 'Name' }
184
+ */
185
+ label?: string | Record<string, string>;
186
+ /**
187
+ * 字段值的多语言标签映射
188
+ * @example
189
+ * valueLabels: {
190
+ * active: { zh: '激活', en: 'Active' },
191
+ * inactive: { zh: '未激活', en: 'Inactive' }
192
+ * }
193
+ */
194
+ valueLabels?: Record<string, Record<string, string>>;
146
195
  sensitive?: boolean;
147
196
  formatter?: (value: any) => string;
148
197
  }
@@ -159,3 +208,97 @@ export interface ControllerAuditOptions {
159
208
  export interface MethodAuditOptions {
160
209
  enabled?: boolean;
161
210
  }
211
+ /**
212
+ * 变更详情
213
+ */
214
+ export interface ChangeDetail {
215
+ fieldName: string;
216
+ fieldLabels?: Record<string, string>;
217
+ oldValue: any;
218
+ newValue: any;
219
+ displayOldValue?: Record<string, string>;
220
+ displayNewValue?: Record<string, string>;
221
+ changeType: ChangeType;
222
+ }
223
+ /**
224
+ * 回滚操作
225
+ */
226
+ export interface RollbackAction {
227
+ type: RollbackActionType;
228
+ action: string;
229
+ params: Record<string, any>;
230
+ order: number;
231
+ handler?: string;
232
+ }
233
+ /**
234
+ * 操作模板配置(用于数据库存储)
235
+ */
236
+ export interface OperationTemplateData {
237
+ key: string;
238
+ entityName: string;
239
+ operation: AuditOperation;
240
+ nameTemplates: Record<string, string>;
241
+ descriptionTemplates: Record<string, string>;
242
+ fieldLabels?: Record<string, Record<string, string>>;
243
+ valueDisplays?: Record<string, Record<string, Record<string, string>>>;
244
+ }
245
+ /**
246
+ * 手动操作日志数据
247
+ */
248
+ export interface ManualOperationData {
249
+ transactionId: string;
250
+ operationTemplateKey: string;
251
+ descriptionParams: Record<string, any>;
252
+ userId?: string;
253
+ username?: string;
254
+ requestIp?: string;
255
+ rollbackActions?: RollbackAction[];
256
+ }
257
+ /**
258
+ * 手动日志记录选项(支持三种模式)
259
+ */
260
+ export interface ManualLogOptions {
261
+ templateKey?: string;
262
+ descriptionParams?: Record<string, any>;
263
+ description?: string | Record<string, string>;
264
+ descriptionTemplate?: Record<string, string>;
265
+ userId?: string;
266
+ username?: string;
267
+ requestIp?: string;
268
+ rollbackActions?: RollbackAction[];
269
+ transactionId?: string;
270
+ autoCreateTransaction?: boolean;
271
+ }
272
+ /**
273
+ * 方法审计选项(支持模板和回滚)
274
+ */
275
+ export interface AuditOperationOptions {
276
+ templateKey: string;
277
+ descriptionParams?: (args: any[], result: any, context: any) => Record<string, any>;
278
+ rollbackActions?: (args: any[], result: any, context: any) => RollbackAction[];
279
+ autoTransaction?: boolean;
280
+ }
281
+ /**
282
+ * 增强的实体审计配置(支持多语言)
283
+ */
284
+ export interface EnhancedEntityAuditConfig extends EntityAuditConfig {
285
+ templateKey?: string;
286
+ fieldLabels?: Record<string, Record<string, string>>;
287
+ valueDisplays?: Record<string, Record<string, Record<string, string>>>;
288
+ }
289
+ /**
290
+ * 事务描述结果
291
+ */
292
+ export interface TransactionDescription {
293
+ operationName: string;
294
+ description: string;
295
+ changes: Array<{
296
+ entityName?: string;
297
+ entityId?: string;
298
+ operation?: AuditOperation;
299
+ type?: string;
300
+ description: string;
301
+ details: any;
302
+ createdAt: Date;
303
+ }>;
304
+ }
@@ -0,0 +1,141 @@
1
+ import { AuditContextService } from './audit-context.service';
2
+ import { EntityAuditService } from './entity-audit.service';
3
+ import { AuditOperation } from '../enums';
4
+ /**
5
+ * 审计动作选项
6
+ */
7
+ export interface AuditActionOptions {
8
+ /**
9
+ * 动作名称,如 'createOrder', 'updateUser'
10
+ */
11
+ actionName: string;
12
+ /**
13
+ * 操作模板键(可选)
14
+ * @example 'order.create'
15
+ */
16
+ operationTemplateKey?: string;
17
+ /**
18
+ * 描述参数,用于模板填充
19
+ * @example { productCount: 3, receiver: '张三', totalAmount: 299.99 }
20
+ */
21
+ descriptionParams?: Record<string, any>;
22
+ /**
23
+ * 自定义元数据
24
+ */
25
+ metadata?: Record<string, any>;
26
+ }
27
+ /**
28
+ * 审计动作结果
29
+ */
30
+ export interface AuditActionResult {
31
+ actionId: string;
32
+ actionName: string;
33
+ entityChanges: Array<{
34
+ entityType: string;
35
+ entityId: string;
36
+ operation: string;
37
+ sequence: number;
38
+ }>;
39
+ duration: number;
40
+ success: boolean;
41
+ error?: Error;
42
+ }
43
+ /**
44
+ * 审计动作服务
45
+ * 提供声明式的审计动作管理,自动关联同一业务操作的所有实体变化
46
+ */
47
+ export declare class AuditActionService {
48
+ private readonly contextService;
49
+ private readonly auditService;
50
+ constructor(contextService: AuditContextService, auditService: EntityAuditService);
51
+ /**
52
+ * 在审计动作上下文中执行操作
53
+ * 自动关联该动作内的所有实体变化
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const result = await auditActionService.executeAction(
58
+ * {
59
+ * actionName: 'createOrder',
60
+ * operationTemplateKey: 'order.create',
61
+ * descriptionParams: {
62
+ * productCount: orderItems.length,
63
+ * receiver: order.receiverName,
64
+ * totalAmount: order.totalAmount,
65
+ * address: order.shippingAddress,
66
+ * },
67
+ * },
68
+ * async () => {
69
+ * // 1. 创建订单
70
+ * const order = await this.orderRepository.save(newOrder);
71
+ *
72
+ * // 2. 创建订单项
73
+ * await this.orderItemRepository.save(orderItems);
74
+ *
75
+ * // 3. 扣减库存
76
+ * await this.inventoryService.deduct(orderItems);
77
+ *
78
+ * // 4. 创建物流信息
79
+ * await this.shippingService.create(order.id);
80
+ *
81
+ * return order;
82
+ * }
83
+ * );
84
+ *
85
+ * // 结果中包含所有实体变化:
86
+ * // result.entityChanges = [
87
+ * // { entityType: 'Order', entityId: '1', operation: 'CREATE', sequence: 1 },
88
+ * // { entityType: 'OrderItem', entityId: '1', operation: 'CREATE', sequence: 2 },
89
+ * // { entityType: 'OrderItem', entityId: '2', operation: 'CREATE', sequence: 3 },
90
+ * // { entityType: 'Inventory', entityId: '1', operation: 'UPDATE', sequence: 4 },
91
+ * // { entityType: 'Shipping', entityId: '1', operation: 'CREATE', sequence: 5 },
92
+ * // ]
93
+ * ```
94
+ */
95
+ executeAction<T>(options: AuditActionOptions, operation: () => Promise<T>): Promise<AuditActionResult>;
96
+ /**
97
+ * 记录审计动作汇总日志
98
+ */
99
+ private recordActionSummary;
100
+ /**
101
+ * 获取审计动作的所有实体变化
102
+ */
103
+ getActionAuditLogs(actionId: string): Promise<{
104
+ actionId: string;
105
+ logs: import("..").EntityAuditLogEntity[];
106
+ summary: {
107
+ totalChanges: number;
108
+ operations: {
109
+ [k: string]: number;
110
+ };
111
+ entities: {
112
+ [k: string]: number;
113
+ };
114
+ };
115
+ }>;
116
+ /**
117
+ * 获取请求内的所有审计动作
118
+ */
119
+ getRequestActions(requestId: string): Promise<{
120
+ requestId: string;
121
+ actions: {
122
+ actionId: string;
123
+ actionName: string;
124
+ entityChanges: {
125
+ entityType: string;
126
+ entityId: string;
127
+ operation: AuditOperation;
128
+ sequence: number;
129
+ timestamp: Date;
130
+ }[];
131
+ logs: import("..").EntityAuditLogEntity[];
132
+ }[];
133
+ noActionLogs: import("..").EntityAuditLogEntity[];
134
+ summary: {
135
+ totalActions: number;
136
+ totalChanges: number;
137
+ };
138
+ }>;
139
+ private groupByOperation;
140
+ private groupByEntity;
141
+ }