@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.
- package/audit/audit.module.js +42 -2
- package/audit/controllers/audit.controller.d.ts +64 -0
- package/audit/controllers/audit.controller.js +50 -0
- package/audit/decorators/audit-action.decorator.d.ts +74 -0
- package/audit/decorators/audit-action.decorator.js +42 -0
- package/audit/decorators/audit-controller.decorator.d.ts +1 -1
- package/audit/decorators/audit-controller.decorator.js +2 -2
- package/audit/decorators/entity-audit.decorator.d.ts +78 -2
- package/audit/decorators/entity-audit.decorator.js +145 -4
- package/audit/decorators/index.d.ts +2 -0
- package/audit/decorators/index.js +2 -0
- package/audit/entities/audit-action-summary.entity.d.ts +23 -0
- package/audit/entities/audit-action-summary.entity.js +101 -0
- package/audit/entities/entity-audit-log.entity.d.ts +8 -0
- package/audit/entities/entity-audit-log.entity.js +54 -2
- package/audit/entities/entity-transaction.entity.d.ts +8 -2
- package/audit/entities/entity-transaction.entity.js +39 -3
- package/audit/entities/index.d.ts +3 -0
- package/audit/entities/index.js +3 -0
- package/audit/entities/manual-operation-log.entity.js +8 -1
- package/audit/enums/audit.enums.d.ts +22 -6
- package/audit/enums/audit.enums.js +27 -9
- package/audit/index.d.ts +4 -1
- package/audit/index.js +25 -2
- package/audit/interceptors/audit-action.interceptor.d.ts +38 -0
- package/audit/interceptors/audit-action.interceptor.js +215 -0
- package/audit/interceptors/index.d.ts +1 -0
- package/audit/interceptors/index.js +1 -0
- package/audit/interfaces/audit.interfaces.d.ts +145 -2
- package/audit/services/audit-action.service.d.ts +141 -0
- package/audit/services/audit-action.service.js +244 -0
- package/audit/services/audit-context.service.d.ts +82 -0
- package/audit/services/audit-context.service.js +170 -0
- package/audit/services/entity-audit.service.d.ts +174 -4
- package/audit/services/entity-audit.service.js +515 -14
- package/audit/services/index.d.ts +3 -0
- package/audit/services/index.js +3 -0
- package/audit/services/manual-audit-log.service.d.ts +24 -23
- package/audit/services/manual-audit-log.service.js +32 -53
- package/audit/services/operation-description.service.d.ts +13 -3
- package/audit/services/operation-description.service.js +161 -24
- package/audit/services/transaction-audit.service.js +3 -3
- package/audit/subscribers/entity-audit.subscriber.d.ts +4 -0
- package/audit/subscribers/entity-audit.subscriber.js +47 -0
- package/file-upload/controllers/file-access.controller.d.ts +23 -0
- package/file-upload/controllers/file-access.controller.js +128 -0
- package/file-upload/decorators/csv-data.decorator.d.ts +44 -0
- package/file-upload/decorators/csv-data.decorator.js +131 -0
- package/file-upload/decorators/excel-data.decorator.d.ts +44 -0
- package/file-upload/decorators/excel-data.decorator.js +125 -0
- package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
- package/file-upload/decorators/file-upload.decorator.js +172 -0
- package/file-upload/decorators/index.d.ts +4 -0
- package/file-upload/decorators/index.js +20 -0
- package/file-upload/decorators/process.decorator.d.ts +40 -0
- package/file-upload/decorators/process.decorator.js +52 -0
- package/file-upload/dto/create-file.dto.d.ts +24 -0
- package/file-upload/dto/create-file.dto.js +112 -0
- package/file-upload/dto/find-files.dto.d.ts +15 -0
- package/file-upload/dto/find-files.dto.js +76 -0
- package/file-upload/dto/index.d.ts +4 -0
- package/file-upload/dto/index.js +20 -0
- package/file-upload/dto/pagination.dto.d.ts +7 -0
- package/file-upload/dto/pagination.dto.js +39 -0
- package/file-upload/dto/update-file.dto.d.ts +16 -0
- package/file-upload/dto/update-file.dto.js +71 -0
- package/file-upload/entities/file-metadata.entity.d.ts +22 -0
- package/file-upload/entities/file-metadata.entity.js +84 -0
- package/file-upload/entities/file.entity.d.ts +129 -0
- package/file-upload/entities/file.entity.js +384 -0
- package/file-upload/entities/index.d.ts +2 -0
- package/file-upload/entities/index.js +18 -0
- package/file-upload/enums/file-type.enum.d.ts +72 -0
- package/file-upload/enums/file-type.enum.js +212 -0
- package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
- package/file-upload/exceptions/file-upload.exception.js +120 -0
- package/file-upload/exceptions/index.d.ts +1 -0
- package/file-upload/exceptions/index.js +17 -0
- package/file-upload/file-upload.module.d.ts +89 -0
- package/file-upload/file-upload.module.js +264 -0
- package/file-upload/index.d.ts +26 -0
- package/file-upload/index.js +59 -0
- package/file-upload/interceptors/file-upload.interceptor.d.ts +48 -0
- package/file-upload/interceptors/file-upload.interceptor.js +434 -0
- package/file-upload/interceptors/index.d.ts +1 -0
- package/file-upload/interceptors/index.js +17 -0
- package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
- package/file-upload/interfaces/custom-file-type.interface.js +2 -0
- package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
- package/file-upload/interfaces/file-buffer.interface.js +2 -0
- package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
- package/file-upload/interfaces/file-entity.interface.js +28 -0
- package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
- package/file-upload/interfaces/file-metadata.interface.js +2 -0
- package/file-upload/interfaces/file-upload-options.interface.d.ts +117 -0
- package/file-upload/interfaces/file-upload-options.interface.js +2 -0
- package/file-upload/interfaces/index.d.ts +7 -0
- package/file-upload/interfaces/index.js +24 -0
- package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
- package/file-upload/interfaces/storage-provider.interface.js +2 -0
- package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
- package/file-upload/interfaces/upload-options.interface.js +2 -0
- package/file-upload/providers/index.d.ts +2 -0
- package/file-upload/providers/index.js +18 -0
- package/file-upload/providers/local-storage.provider.d.ts +98 -0
- package/file-upload/providers/local-storage.provider.js +484 -0
- package/file-upload/providers/s3-storage.provider.d.ts +87 -0
- package/file-upload/providers/s3-storage.provider.js +455 -0
- package/file-upload/services/file-signature-validator.service.d.ts +118 -0
- package/file-upload/services/file-signature-validator.service.js +376 -0
- package/file-upload/services/file.service.d.ts +190 -0
- package/file-upload/services/file.service.js +609 -0
- package/file-upload/services/index.d.ts +4 -0
- package/file-upload/services/index.js +20 -0
- package/file-upload/services/malicious-file-detector.service.d.ts +274 -0
- package/file-upload/services/malicious-file-detector.service.js +1035 -0
- package/file-upload/services/mime-registry.service.d.ts +47 -0
- package/file-upload/services/mime-registry.service.js +167 -0
- package/file-upload/utils/checksum.util.d.ts +28 -0
- package/file-upload/utils/checksum.util.js +65 -0
- package/file-upload/utils/dynamic-import.util.d.ts +50 -0
- package/file-upload/utils/dynamic-import.util.js +144 -0
- package/file-upload/utils/filename.util.d.ts +59 -0
- package/file-upload/utils/filename.util.js +184 -0
- package/file-upload/utils/filepath.util.d.ts +70 -0
- package/file-upload/utils/filepath.util.js +152 -0
- package/file-upload/utils/index.d.ts +4 -0
- package/file-upload/utils/index.js +20 -0
- package/http-client/http-client.module.js +1 -5
- package/index.d.ts +3 -1
- package/index.js +4 -1
- package/package.json +4 -5
- package/redis-lock/lock-heartbeat.service.d.ts +2 -2
- package/redis-lock/lock-heartbeat.service.js +4 -4
- package/redis-lock/redis-lock.service.d.ts +18 -0
- package/redis-lock/redis-lock.service.js +38 -8
- package/setup/bootstrap.setup.d.ts +1 -0
- package/setup/bootstrap.setup.js +1 -0
- package/setup/schedule.decorator.js +18 -8
- package/shared/index.d.ts +1 -1
- package/shared/index.js +1 -1
- package/shared/{serviceRegistryModule.js → service-registry.module.js} +9 -16
- package/shared/services/index.d.ts +0 -1
- package/shared/services/index.js +0 -1
- package/transaction/__tests__/mocks.d.ts +9 -0
- package/transaction/__tests__/mocks.js +33 -0
- package/transaction/base-service-transaction.d.ts +99 -0
- package/transaction/base-service-transaction.js +286 -0
- package/transaction/cls-compatibility.service.d.ts +55 -0
- package/transaction/cls-compatibility.service.js +127 -0
- package/transaction/data-source-registry.d.ts +91 -0
- package/transaction/data-source-registry.js +349 -0
- package/transaction/database-adapter.d.ts +44 -0
- package/transaction/database-adapter.js +240 -0
- package/transaction/decorators/entity-datasource.decorator.d.ts +62 -0
- package/transaction/decorators/entity-datasource.decorator.js +105 -0
- package/transaction/index.d.ts +14 -0
- package/transaction/index.js +57 -0
- package/transaction/logging-transactional.interceptor.d.ts +18 -0
- package/transaction/logging-transactional.interceptor.js +163 -0
- package/transaction/transaction-context.service.d.ts +137 -0
- package/transaction/transaction-context.service.js +411 -0
- package/transaction/transaction-manager.d.ts +230 -0
- package/transaction/transaction-manager.js +1001 -0
- package/transaction/transaction-synchronization.d.ts +171 -0
- package/transaction/transaction-synchronization.js +380 -0
- package/transaction/transaction.errors.d.ts +91 -0
- package/transaction/transaction.errors.js +206 -0
- package/transaction/transaction.module.d.ts +30 -0
- package/transaction/transaction.module.js +98 -0
- package/transaction/transactional.decorator.d.ts +82 -0
- package/transaction/transactional.decorator.js +319 -0
- package/transaction/typeorm-module-wrapper.d.ts +96 -0
- package/transaction/typeorm-module-wrapper.js +197 -0
- package/validators/file-mimetype.validator.d.ts +0 -2
- package/validators/file-mimetype.validator.js +4 -6
- package/validators/is-exists.validator.d.ts +2 -5
- package/validators/is-exists.validator.js +4 -6
- package/validators/is-unique.validator.d.ts +2 -5
- package/validators/is-unique.validator.js +6 -11
- package/shared/services/validator.service.d.ts +0 -3
- package/shared/services/validator.service.js +0 -20
- /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
package/audit/audit.module.js
CHANGED
|
@@ -67,6 +67,27 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
67
67
|
},
|
|
68
68
|
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
69
69
|
},
|
|
70
|
+
{
|
|
71
|
+
provide: (0, typeorm_1.getRepositoryToken)(entities_1.OperationTemplateEntity),
|
|
72
|
+
useFactory: (dataSource) => {
|
|
73
|
+
return dataSource.getRepository(entities_1.OperationTemplateEntity);
|
|
74
|
+
},
|
|
75
|
+
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
provide: (0, typeorm_1.getRepositoryToken)(entities_1.ManualOperationLogEntity),
|
|
79
|
+
useFactory: (dataSource) => {
|
|
80
|
+
return dataSource.getRepository(entities_1.ManualOperationLogEntity);
|
|
81
|
+
},
|
|
82
|
+
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
provide: (0, typeorm_1.getRepositoryToken)(entities_1.AuditActionSummaryEntity),
|
|
86
|
+
useFactory: (dataSource) => {
|
|
87
|
+
return dataSource.getRepository(entities_1.AuditActionSummaryEntity);
|
|
88
|
+
},
|
|
89
|
+
inject: [(0, typeorm_1.getDataSourceToken)(auditConnectionName)],
|
|
90
|
+
},
|
|
70
91
|
{
|
|
71
92
|
provide: 'AUDIT_ENTITY_MANAGER',
|
|
72
93
|
useFactory: (dataSource) => {
|
|
@@ -78,8 +99,14 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
78
99
|
return {
|
|
79
100
|
module: AuditModule_1,
|
|
80
101
|
imports: [
|
|
81
|
-
//
|
|
82
|
-
typeorm_1.TypeOrmModule.forFeature([
|
|
102
|
+
// ��计日志存储到指定的数据库连接
|
|
103
|
+
typeorm_1.TypeOrmModule.forFeature([
|
|
104
|
+
entities_1.EntityAuditLogEntity,
|
|
105
|
+
entities_1.EntityTransactionEntity,
|
|
106
|
+
entities_1.OperationTemplateEntity,
|
|
107
|
+
entities_1.ManualOperationLogEntity,
|
|
108
|
+
entities_1.AuditActionSummaryEntity,
|
|
109
|
+
], auditConnectionName),
|
|
83
110
|
nestjs_cls_1.ClsModule.forRoot({
|
|
84
111
|
global: true,
|
|
85
112
|
middleware: { mount: true },
|
|
@@ -105,7 +132,10 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
105
132
|
...repositoryProviders,
|
|
106
133
|
services_1.EntityAuditService,
|
|
107
134
|
services_1.TransactionAuditService,
|
|
135
|
+
services_1.OperationDescriptionService,
|
|
136
|
+
services_1.AuditActionService,
|
|
108
137
|
interceptors_1.AuditInterceptor,
|
|
138
|
+
interceptors_1.AuditActionInterceptor,
|
|
109
139
|
...subscriberProviders,
|
|
110
140
|
],
|
|
111
141
|
exports: [
|
|
@@ -114,7 +144,11 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
114
144
|
services_1.MultiDatabaseService,
|
|
115
145
|
services_1.EntityAuditService,
|
|
116
146
|
services_1.TransactionAuditService,
|
|
147
|
+
services_1.OperationDescriptionService,
|
|
148
|
+
services_1.AuditActionService,
|
|
117
149
|
interceptors_1.AuditInterceptor,
|
|
150
|
+
interceptors_1.AuditActionInterceptor,
|
|
151
|
+
(0, typeorm_1.getRepositoryToken)(entities_1.AuditActionSummaryEntity),
|
|
118
152
|
],
|
|
119
153
|
};
|
|
120
154
|
}
|
|
@@ -226,7 +260,10 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
226
260
|
...repositoryProviders,
|
|
227
261
|
services_1.EntityAuditService,
|
|
228
262
|
services_1.TransactionAuditService,
|
|
263
|
+
services_1.OperationDescriptionService,
|
|
264
|
+
services_1.AuditActionService,
|
|
229
265
|
interceptors_1.AuditInterceptor,
|
|
266
|
+
interceptors_1.AuditActionInterceptor,
|
|
230
267
|
],
|
|
231
268
|
exports: [
|
|
232
269
|
services_1.AuditContextService,
|
|
@@ -234,7 +271,10 @@ let AuditModule = AuditModule_1 = class AuditModule {
|
|
|
234
271
|
services_1.MultiDatabaseService,
|
|
235
272
|
services_1.EntityAuditService,
|
|
236
273
|
services_1.TransactionAuditService,
|
|
274
|
+
services_1.OperationDescriptionService,
|
|
275
|
+
services_1.AuditActionService,
|
|
237
276
|
interceptors_1.AuditInterceptor,
|
|
277
|
+
interceptors_1.AuditActionInterceptor,
|
|
238
278
|
],
|
|
239
279
|
};
|
|
240
280
|
}
|
|
@@ -41,4 +41,68 @@ export declare class AuditController {
|
|
|
41
41
|
* 回滚审计事务
|
|
42
42
|
*/
|
|
43
43
|
rollbackTransaction(transactionId: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 查询审计动作汇总记录
|
|
46
|
+
*/
|
|
47
|
+
getAuditActions(userId?: string, username?: string, actionName?: string, success?: string, startTime?: string, endTime?: string, page?: number, limit?: number): Promise<PageDto<import("../entities").AuditActionSummaryEntity>>;
|
|
48
|
+
/**
|
|
49
|
+
* 查询单个审计动作的详细信息
|
|
50
|
+
*/
|
|
51
|
+
getAuditActionDetail(actionId: string): Promise<{
|
|
52
|
+
summary: {
|
|
53
|
+
id: string;
|
|
54
|
+
actionName: string;
|
|
55
|
+
operationTemplateKey: string;
|
|
56
|
+
description: string;
|
|
57
|
+
descriptionParams: Record<string, any>;
|
|
58
|
+
success: boolean;
|
|
59
|
+
errorMessage: string;
|
|
60
|
+
duration: number;
|
|
61
|
+
userId: string;
|
|
62
|
+
username: string;
|
|
63
|
+
requestId: string;
|
|
64
|
+
requestIp: string;
|
|
65
|
+
userAgent: string;
|
|
66
|
+
entityChangesCount: number;
|
|
67
|
+
entityTypes: string[];
|
|
68
|
+
operationStats: Record<string, number>;
|
|
69
|
+
createdAt: Date;
|
|
70
|
+
metadata: Record<string, any>;
|
|
71
|
+
};
|
|
72
|
+
entityChanges: EntityAuditLogEntity[];
|
|
73
|
+
detailedChanges: {
|
|
74
|
+
id: string;
|
|
75
|
+
entityType: string;
|
|
76
|
+
entityId: string;
|
|
77
|
+
operation: import("..").AuditOperation;
|
|
78
|
+
operationLabel: string;
|
|
79
|
+
description: string;
|
|
80
|
+
sequenceInAction: number;
|
|
81
|
+
createdAt: Date;
|
|
82
|
+
oldValue: Record<string, any>;
|
|
83
|
+
newValue: Record<string, any>;
|
|
84
|
+
fieldChanges: {
|
|
85
|
+
field: string;
|
|
86
|
+
fieldLabel: string;
|
|
87
|
+
oldValue: any;
|
|
88
|
+
newValue: any;
|
|
89
|
+
changeType: "added" | "removed" | "modified" | "unchanged";
|
|
90
|
+
displayOldValue?: string;
|
|
91
|
+
displayNewValue?: string;
|
|
92
|
+
}[];
|
|
93
|
+
changedFieldsCount: number;
|
|
94
|
+
changedFields: string[];
|
|
95
|
+
}[];
|
|
96
|
+
statistics: {
|
|
97
|
+
totalChanges: number;
|
|
98
|
+
totalFieldChanges: number;
|
|
99
|
+
byEntityType: Record<string, number>;
|
|
100
|
+
byOperation: Record<string, number>;
|
|
101
|
+
operationSequence: {
|
|
102
|
+
sequence: number;
|
|
103
|
+
entityType: string;
|
|
104
|
+
operation: import("..").AuditOperation;
|
|
105
|
+
}[];
|
|
106
|
+
};
|
|
107
|
+
}>;
|
|
44
108
|
}
|
|
@@ -93,6 +93,31 @@ let AuditController = class AuditController {
|
|
|
93
93
|
return this.transactionAuditService.rollbackTransaction(transactionId);
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* 查询审计动作汇总记录
|
|
98
|
+
*/
|
|
99
|
+
getAuditActions(userId_1, username_1, actionName_1, success_1, startTime_1, endTime_1) {
|
|
100
|
+
return __awaiter(this, arguments, void 0, function* (userId, username, actionName, success, startTime, endTime, page = 1, limit = 20) {
|
|
101
|
+
return this.entityAuditService.getAuditActions({
|
|
102
|
+
userId,
|
|
103
|
+
username,
|
|
104
|
+
actionName,
|
|
105
|
+
success: success ? success === 'true' : undefined,
|
|
106
|
+
startTime: startTime ? new Date(startTime) : undefined,
|
|
107
|
+
endTime: endTime ? new Date(endTime) : undefined,
|
|
108
|
+
page,
|
|
109
|
+
limit,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 查询单个审计动作的详细信息
|
|
115
|
+
*/
|
|
116
|
+
getAuditActionDetail(actionId) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
return this.entityAuditService.getAuditActionDetail(actionId);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
96
121
|
};
|
|
97
122
|
exports.AuditController = AuditController;
|
|
98
123
|
__decorate([
|
|
@@ -158,6 +183,31 @@ __decorate([
|
|
|
158
183
|
__metadata("design:paramtypes", [String]),
|
|
159
184
|
__metadata("design:returntype", Promise)
|
|
160
185
|
], AuditController.prototype, "rollbackTransaction", null);
|
|
186
|
+
__decorate([
|
|
187
|
+
(0, common_1.Get)('actions'),
|
|
188
|
+
(0, swagger_1.ApiOperation)({ summary: '查询审计动作汇总记录' }),
|
|
189
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: '返回审计动作汇总列表' }),
|
|
190
|
+
__param(0, (0, common_1.Query)('userId')),
|
|
191
|
+
__param(1, (0, common_1.Query)('username')),
|
|
192
|
+
__param(2, (0, common_1.Query)('actionName')),
|
|
193
|
+
__param(3, (0, common_1.Query)('success')),
|
|
194
|
+
__param(4, (0, common_1.Query)('startTime')),
|
|
195
|
+
__param(5, (0, common_1.Query)('endTime')),
|
|
196
|
+
__param(6, (0, common_1.Query)('page')),
|
|
197
|
+
__param(7, (0, common_1.Query)('limit')),
|
|
198
|
+
__metadata("design:type", Function),
|
|
199
|
+
__metadata("design:paramtypes", [String, String, String, String, String, String, Number, Number]),
|
|
200
|
+
__metadata("design:returntype", Promise)
|
|
201
|
+
], AuditController.prototype, "getAuditActions", null);
|
|
202
|
+
__decorate([
|
|
203
|
+
(0, common_1.Get)('actions/:actionId'),
|
|
204
|
+
(0, swagger_1.ApiOperation)({ summary: '查询审计动作详细信息' }),
|
|
205
|
+
(0, swagger_1.ApiResponse)({ status: 200, description: '返回审计动作详细信息' }),
|
|
206
|
+
__param(0, (0, common_1.Param)('actionId')),
|
|
207
|
+
__metadata("design:type", Function),
|
|
208
|
+
__metadata("design:paramtypes", [String]),
|
|
209
|
+
__metadata("design:returntype", Promise)
|
|
210
|
+
], AuditController.prototype, "getAuditActionDetail", null);
|
|
161
211
|
exports.AuditController = AuditController = __decorate([
|
|
162
212
|
(0, common_1.Controller)('audit'),
|
|
163
213
|
(0, swagger_1.ApiTags)('audit'),
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { AuditParamsContext } from '../services/audit-context.service';
|
|
2
|
+
export declare const AUDIT_ACTION_METADATA = "AUDIT_ACTION_METADATA";
|
|
3
|
+
/**
|
|
4
|
+
* 审计动作选项
|
|
5
|
+
*/
|
|
6
|
+
export interface AuditActionOptions {
|
|
7
|
+
/**
|
|
8
|
+
* 操作模板键(可选)
|
|
9
|
+
* @example 'order.create'
|
|
10
|
+
*/
|
|
11
|
+
templateKey?: string;
|
|
12
|
+
/**
|
|
13
|
+
* 参数构建器,用于从请求和实体变更中提取描述参数
|
|
14
|
+
* @param context - 包含 req, result, error, entityChanges 的上下文
|
|
15
|
+
* @returns 描述参数对象
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* paramsBuilder: (context) => {
|
|
19
|
+
* const order = context.findEntity('Order', 'CREATE');
|
|
20
|
+
* const items = context.findEntities('OrderItem', 'CREATE');
|
|
21
|
+
* return {
|
|
22
|
+
* 'order.sn': order?.newValue.orderSn,
|
|
23
|
+
* 'product.count': items.length,
|
|
24
|
+
* 'receiver': order?.newValue.receiverName,
|
|
25
|
+
* };
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
paramsBuilder?: (context: AuditParamsContext) => Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* 是否启用审计(默认 true)
|
|
31
|
+
*/
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 扩展元数据
|
|
35
|
+
*/
|
|
36
|
+
metadata?: Record<string, any>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 审计动作装饰器元数据
|
|
40
|
+
*/
|
|
41
|
+
export interface AuditActionMetadata {
|
|
42
|
+
actionName: string;
|
|
43
|
+
options: AuditActionOptions;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 审计动作装饰器
|
|
47
|
+
* 用于在控制器方法上标记审计动作,自动收集该请求中的所有实体变更
|
|
48
|
+
*
|
|
49
|
+
* @param actionName - 操作名称,如 'createOrder', 'cancelOrder'
|
|
50
|
+
* @param options - 审计动作选项
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* @Post()
|
|
55
|
+
* @AuditAction('createOrder', {
|
|
56
|
+
* templateKey: 'order.create',
|
|
57
|
+
* paramsBuilder: (context) => {
|
|
58
|
+
* const order = context.findEntity('Order', 'CREATE');
|
|
59
|
+
* const items = context.findEntities('OrderItem', 'CREATE');
|
|
60
|
+
* return {
|
|
61
|
+
* 'order.sn': order?.newValue.orderSn,
|
|
62
|
+
* 'product.count': items.length,
|
|
63
|
+
* 'product.names': items.map(i => i.metadata?.productName).join('、'),
|
|
64
|
+
* 'receiver': order?.newValue.receiverName,
|
|
65
|
+
* 'totalAmount': order?.newValue.totalAmount,
|
|
66
|
+
* };
|
|
67
|
+
* }
|
|
68
|
+
* })
|
|
69
|
+
* async createOrder(@Body() dto: CreateOrderDto) {
|
|
70
|
+
* return await this.orderService.create(dto);
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function AuditAction(actionName: string, options?: AuditActionOptions): MethodDecorator;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AUDIT_ACTION_METADATA = void 0;
|
|
4
|
+
exports.AuditAction = AuditAction;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
exports.AUDIT_ACTION_METADATA = 'AUDIT_ACTION_METADATA';
|
|
7
|
+
/**
|
|
8
|
+
* 审计动作装饰器
|
|
9
|
+
* 用于在控制器方法上标记审计动作,自动收集该请求中的所有实体变更
|
|
10
|
+
*
|
|
11
|
+
* @param actionName - 操作名称,如 'createOrder', 'cancelOrder'
|
|
12
|
+
* @param options - 审计动作选项
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @Post()
|
|
17
|
+
* @AuditAction('createOrder', {
|
|
18
|
+
* templateKey: 'order.create',
|
|
19
|
+
* paramsBuilder: (context) => {
|
|
20
|
+
* const order = context.findEntity('Order', 'CREATE');
|
|
21
|
+
* const items = context.findEntities('OrderItem', 'CREATE');
|
|
22
|
+
* return {
|
|
23
|
+
* 'order.sn': order?.newValue.orderSn,
|
|
24
|
+
* 'product.count': items.length,
|
|
25
|
+
* 'product.names': items.map(i => i.metadata?.productName).join('、'),
|
|
26
|
+
* 'receiver': order?.newValue.receiverName,
|
|
27
|
+
* 'totalAmount': order?.newValue.totalAmount,
|
|
28
|
+
* };
|
|
29
|
+
* }
|
|
30
|
+
* })
|
|
31
|
+
* async createOrder(@Body() dto: CreateOrderDto) {
|
|
32
|
+
* return await this.orderService.create(dto);
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function AuditAction(actionName, options = {}) {
|
|
37
|
+
const metadata = {
|
|
38
|
+
actionName,
|
|
39
|
+
options: Object.assign({ enabled: true }, options),
|
|
40
|
+
};
|
|
41
|
+
return (0, common_1.SetMetadata)(exports.AUDIT_ACTION_METADATA, metadata);
|
|
42
|
+
}
|
|
@@ -5,7 +5,7 @@ export declare const METHOD_AUDIT_OPTIONS: unique symbol;
|
|
|
5
5
|
* 控制器审计装饰器
|
|
6
6
|
* @param options 控制器审计选项
|
|
7
7
|
*/
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function AuditController(options?: ControllerAuditOptions): ClassDecorator;
|
|
9
9
|
/**
|
|
10
10
|
* 方法审计装饰器
|
|
11
11
|
* @param options 方法审计选项
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.METHOD_AUDIT_OPTIONS = exports.CONTROLLER_AUDIT_OPTIONS = void 0;
|
|
4
|
-
exports.
|
|
4
|
+
exports.AuditController = AuditController;
|
|
5
5
|
exports.AuditMethod = AuditMethod;
|
|
6
6
|
// 元数据键
|
|
7
7
|
exports.CONTROLLER_AUDIT_OPTIONS = Symbol('CONTROLLER_AUDIT_OPTIONS');
|
|
@@ -10,7 +10,7 @@ exports.METHOD_AUDIT_OPTIONS = Symbol('METHOD_AUDIT_OPTIONS');
|
|
|
10
10
|
* 控制器审计装饰器
|
|
11
11
|
* @param options 控制器审计选项
|
|
12
12
|
*/
|
|
13
|
-
function
|
|
13
|
+
function AuditController(options) {
|
|
14
14
|
return (target) => {
|
|
15
15
|
Reflect.defineMetadata(exports.CONTROLLER_AUDIT_OPTIONS, options || {}, target);
|
|
16
16
|
};
|
|
@@ -3,11 +3,87 @@ export declare const ENTITY_AUDIT_OPTIONS: unique symbol;
|
|
|
3
3
|
export declare const FIELD_AUDIT_OPTIONS: unique symbol;
|
|
4
4
|
/**
|
|
5
5
|
* 实体审计装饰器
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* 支持基础审计配置和多语言标签。
|
|
9
|
+
* 字段标签和值标签请使用 @AuditField({ label: { zh: '姓名', en: 'Name' } })
|
|
10
|
+
*
|
|
6
11
|
* @param options 审计配置选项
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // 基础用法
|
|
15
|
+
* @AuditEntity({
|
|
16
|
+
* enabled: true,
|
|
17
|
+
* label: { zh: '订单', en: 'Order' },
|
|
18
|
+
* excludeFields: ['password'],
|
|
19
|
+
* maskFields: ['email']
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // 指定模板键
|
|
24
|
+
* @AuditEntity({
|
|
25
|
+
* enabled: true,
|
|
26
|
+
* label: { zh: '用户', en: 'User' },
|
|
27
|
+
* templateKey: 'user',
|
|
28
|
+
* })
|
|
7
29
|
*/
|
|
8
|
-
export declare function
|
|
30
|
+
export declare function AuditEntity(options?: EntityAuditConfig): ClassDecorator;
|
|
9
31
|
/**
|
|
10
32
|
* 字段审计装饰器
|
|
11
|
-
* @param options
|
|
33
|
+
* @param options 字段显示选项(支持多语言 label 和 valueLabels)
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // 单语言
|
|
37
|
+
* @AuditField({ label: '姓名' })
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // 多语言
|
|
41
|
+
* @AuditField({ label: { zh: '姓名', en: 'Name' } })
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // 带值标签映射
|
|
45
|
+
* @AuditField({
|
|
46
|
+
* label: { zh: '状态', en: 'Status' },
|
|
47
|
+
* valueLabels: {
|
|
48
|
+
* active: { zh: '激活', en: 'Active' },
|
|
49
|
+
* inactive: { zh: '未激活', en: 'Inactive' }
|
|
50
|
+
* }
|
|
51
|
+
* })
|
|
12
52
|
*/
|
|
13
53
|
export declare function AuditField(options?: FieldDisplayOptions): PropertyDecorator;
|
|
54
|
+
/**
|
|
55
|
+
* 获取实体审计配置
|
|
56
|
+
* @param target 目标类
|
|
57
|
+
* @returns 审计配置
|
|
58
|
+
*/
|
|
59
|
+
export declare function getEntityAuditConfig(target: any): EntityAuditConfig;
|
|
60
|
+
/**
|
|
61
|
+
* 获取字段审计配置
|
|
62
|
+
* @param target 目标类
|
|
63
|
+
* @returns 字段配置映射
|
|
64
|
+
*/
|
|
65
|
+
export declare function getFieldAuditConfig(target: any): Record<string, FieldDisplayOptions>;
|
|
66
|
+
/**
|
|
67
|
+
* 获取字段的标签(支持多语言)
|
|
68
|
+
* @param target 目标类
|
|
69
|
+
* @param fieldName 字段名
|
|
70
|
+
* @param language 语言代码(默认:zh)
|
|
71
|
+
* @returns 字段标签
|
|
72
|
+
*/
|
|
73
|
+
export declare function getFieldLabel(target: any, fieldName: string, language?: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* 获取字段值的标签(支持多语言)
|
|
76
|
+
* @param target 目标类
|
|
77
|
+
* @param fieldName 字段名
|
|
78
|
+
* @param value 值
|
|
79
|
+
* @param language 语言代码(默认:zh)
|
|
80
|
+
* @returns 值的标签
|
|
81
|
+
*/
|
|
82
|
+
export declare function getFieldValueLabel(target: any, fieldName: string, value: any, language?: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* 获取实体的标签(支持多语言)
|
|
85
|
+
* @param target 目标类
|
|
86
|
+
* @param language 语言代码(默认:zh)
|
|
87
|
+
* @returns 实体标签
|
|
88
|
+
*/
|
|
89
|
+
export declare function getEntityLabel(target: any, language?: string): string;
|
|
@@ -1,23 +1,84 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FIELD_AUDIT_OPTIONS = exports.ENTITY_AUDIT_OPTIONS = void 0;
|
|
4
|
-
exports.
|
|
4
|
+
exports.AuditEntity = AuditEntity;
|
|
5
5
|
exports.AuditField = AuditField;
|
|
6
|
+
exports.getEntityAuditConfig = getEntityAuditConfig;
|
|
7
|
+
exports.getFieldAuditConfig = getFieldAuditConfig;
|
|
8
|
+
exports.getFieldLabel = getFieldLabel;
|
|
9
|
+
exports.getFieldValueLabel = getFieldValueLabel;
|
|
10
|
+
exports.getEntityLabel = getEntityLabel;
|
|
6
11
|
// 元数据键
|
|
7
12
|
exports.ENTITY_AUDIT_OPTIONS = Symbol('ENTITY_AUDIT_OPTIONS');
|
|
8
13
|
exports.FIELD_AUDIT_OPTIONS = Symbol('FIELD_AUDIT_OPTIONS');
|
|
9
14
|
/**
|
|
10
15
|
* 实体审计装饰器
|
|
16
|
+
*
|
|
17
|
+
* @description
|
|
18
|
+
* 支持基础审计配置和多语言标签。
|
|
19
|
+
* 字段标签和值标签请使用 @AuditField({ label: { zh: '姓名', en: 'Name' } })
|
|
20
|
+
*
|
|
11
21
|
* @param options 审计配置选项
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // 基础用法
|
|
25
|
+
* @AuditEntity({
|
|
26
|
+
* enabled: true,
|
|
27
|
+
* label: { zh: '订单', en: 'Order' },
|
|
28
|
+
* excludeFields: ['password'],
|
|
29
|
+
* maskFields: ['email']
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // 指定模板键
|
|
34
|
+
* @AuditEntity({
|
|
35
|
+
* enabled: true,
|
|
36
|
+
* label: { zh: '用户', en: 'User' },
|
|
37
|
+
* templateKey: 'user',
|
|
38
|
+
* })
|
|
12
39
|
*/
|
|
13
|
-
function
|
|
40
|
+
function AuditEntity(options) {
|
|
14
41
|
return (target) => {
|
|
15
|
-
|
|
42
|
+
// 存储审计元数据
|
|
43
|
+
const auditOptions = Object.assign({}, options);
|
|
44
|
+
// 去重 maskFields
|
|
45
|
+
if (auditOptions.maskFields && auditOptions.maskFields.length > 0) {
|
|
46
|
+
auditOptions.maskFields = [...new Set(auditOptions.maskFields)];
|
|
47
|
+
}
|
|
48
|
+
// 存储基础审计元数据
|
|
49
|
+
Reflect.defineMetadata(exports.ENTITY_AUDIT_OPTIONS, auditOptions, target);
|
|
50
|
+
// 如果有 templateKey,同时存储到 entity-log 元数据(兼容性)
|
|
51
|
+
if (auditOptions.templateKey) {
|
|
52
|
+
Reflect.defineMetadata('entity-log:enabled', true, target);
|
|
53
|
+
Reflect.defineMetadata('entity-log:options', {
|
|
54
|
+
templateKey: auditOptions.templateKey,
|
|
55
|
+
excludeFields: auditOptions.excludeFields,
|
|
56
|
+
sensitiveFields: auditOptions.maskFields,
|
|
57
|
+
}, target);
|
|
58
|
+
}
|
|
16
59
|
};
|
|
17
60
|
}
|
|
18
61
|
/**
|
|
19
62
|
* 字段审计装饰器
|
|
20
|
-
* @param options
|
|
63
|
+
* @param options 字段显示选项(支持多语言 label 和 valueLabels)
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // 单语言
|
|
67
|
+
* @AuditField({ label: '姓名' })
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // 多语言
|
|
71
|
+
* @AuditField({ label: { zh: '姓名', en: 'Name' } })
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // 带值标签映射
|
|
75
|
+
* @AuditField({
|
|
76
|
+
* label: { zh: '状态', en: 'Status' },
|
|
77
|
+
* valueLabels: {
|
|
78
|
+
* active: { zh: '激活', en: 'Active' },
|
|
79
|
+
* inactive: { zh: '未激活', en: 'Inactive' }
|
|
80
|
+
* }
|
|
81
|
+
* })
|
|
21
82
|
*/
|
|
22
83
|
function AuditField(options) {
|
|
23
84
|
return (target, propertyKey) => {
|
|
@@ -26,3 +87,83 @@ function AuditField(options) {
|
|
|
26
87
|
Reflect.defineMetadata(exports.FIELD_AUDIT_OPTIONS, existingOptions, target.constructor);
|
|
27
88
|
};
|
|
28
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* 获取实体审计配置
|
|
92
|
+
* @param target 目标类
|
|
93
|
+
* @returns 审计配置
|
|
94
|
+
*/
|
|
95
|
+
function getEntityAuditConfig(target) {
|
|
96
|
+
return Reflect.getMetadata(exports.ENTITY_AUDIT_OPTIONS, target) || {};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 获取字段审计配置
|
|
100
|
+
* @param target 目标类
|
|
101
|
+
* @returns 字段配置映射
|
|
102
|
+
*/
|
|
103
|
+
function getFieldAuditConfig(target) {
|
|
104
|
+
return Reflect.getMetadata(exports.FIELD_AUDIT_OPTIONS, target) || {};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 获取字段的标签(支持多语言)
|
|
108
|
+
* @param target 目标类
|
|
109
|
+
* @param fieldName 字段名
|
|
110
|
+
* @param language 语言代码(默认:zh)
|
|
111
|
+
* @returns 字段标签
|
|
112
|
+
*/
|
|
113
|
+
function getFieldLabel(target, fieldName, language = 'zh') {
|
|
114
|
+
var _a;
|
|
115
|
+
const fieldConfig = getFieldAuditConfig(target);
|
|
116
|
+
const label = (_a = fieldConfig[fieldName]) === null || _a === void 0 ? void 0 : _a.label;
|
|
117
|
+
if (!label) {
|
|
118
|
+
return fieldName;
|
|
119
|
+
}
|
|
120
|
+
// 如果是字符串,直接返回
|
|
121
|
+
if (typeof label === 'string') {
|
|
122
|
+
return label;
|
|
123
|
+
}
|
|
124
|
+
// 如果是对象,返回指定语言的值
|
|
125
|
+
return label[language] || label['zh'] || fieldName;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 获取字段值的标签(支持多语言)
|
|
129
|
+
* @param target 目标类
|
|
130
|
+
* @param fieldName 字段名
|
|
131
|
+
* @param value 值
|
|
132
|
+
* @param language 语言代码(默认:zh)
|
|
133
|
+
* @returns 值的标签
|
|
134
|
+
*/
|
|
135
|
+
function getFieldValueLabel(target, fieldName, value, language = 'zh') {
|
|
136
|
+
var _a;
|
|
137
|
+
const fieldConfig = getFieldAuditConfig(target);
|
|
138
|
+
const valueLabels = (_a = fieldConfig[fieldName]) === null || _a === void 0 ? void 0 : _a.valueLabels;
|
|
139
|
+
if (!valueLabels || !valueLabels[value]) {
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
const labelMap = valueLabels[value];
|
|
143
|
+
// 如果是字符串,直接返回
|
|
144
|
+
if (typeof labelMap === 'string') {
|
|
145
|
+
return labelMap;
|
|
146
|
+
}
|
|
147
|
+
// 如果是对象,返回指定语言的值
|
|
148
|
+
return labelMap[language] || labelMap['zh'] || value;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 获取实体的标签(支持多语言)
|
|
152
|
+
* @param target 目标类
|
|
153
|
+
* @param language 语言代码(默认:zh)
|
|
154
|
+
* @returns 实体标签
|
|
155
|
+
*/
|
|
156
|
+
function getEntityLabel(target, language = 'zh') {
|
|
157
|
+
const config = getEntityAuditConfig(target);
|
|
158
|
+
const label = config.label;
|
|
159
|
+
if (!label) {
|
|
160
|
+
// 如果没有配置标签,返回类名
|
|
161
|
+
return target.name || 'Entity';
|
|
162
|
+
}
|
|
163
|
+
// 如果是字符串,直接返回
|
|
164
|
+
if (typeof label === 'string') {
|
|
165
|
+
return label;
|
|
166
|
+
}
|
|
167
|
+
// 如果是对象,返回指定语言的值
|
|
168
|
+
return label[language] || label['zh'] || target.name || 'Entity';
|
|
169
|
+
}
|
|
@@ -16,3 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./entity-audit.decorator"), exports);
|
|
18
18
|
__exportStar(require("./audit-controller.decorator"), exports);
|
|
19
|
+
__exportStar(require("./audit-operation.decorator"), exports);
|
|
20
|
+
__exportStar(require("./audit-action.decorator"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AbstractUuidPrimaryEntity } from '../../common/abstract.entity';
|
|
2
|
+
/**
|
|
3
|
+
* 审计动作汇总实体
|
|
4
|
+
* 记录一次 API 调用的审计摘要信息
|
|
5
|
+
*/
|
|
6
|
+
export declare class AuditActionSummaryEntity extends AbstractUuidPrimaryEntity {
|
|
7
|
+
actionName: string;
|
|
8
|
+
operationTemplateKey: string;
|
|
9
|
+
descriptionParams: Record<string, any>;
|
|
10
|
+
description: string;
|
|
11
|
+
requestId: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
username: string;
|
|
14
|
+
requestIp: string;
|
|
15
|
+
userAgent: string;
|
|
16
|
+
entityChangesCount: number;
|
|
17
|
+
entityTypes: string[];
|
|
18
|
+
operationStats: Record<string, number>;
|
|
19
|
+
success: boolean;
|
|
20
|
+
errorMessage: string;
|
|
21
|
+
duration: number;
|
|
22
|
+
metadata: Record<string, any>;
|
|
23
|
+
}
|