@nest-omni/core 4.1.3-1 → 4.1.3-11
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.d.ts +10 -0
- package/audit/audit.module.js +39 -1
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +9 -1
- package/audit/decorators/audit-controller.decorator.js +11 -2
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +76 -1
- package/audit/decorators/entity-audit.decorator.js +135 -3
- package/audit/decorators/index.d.ts +1 -0
- package/audit/decorators/index.js +1 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +8 -0
- package/audit/entities/entity-audit-log.entity.js +33 -1
- package/audit/entities/entity-transaction.entity.d.ts +10 -0
- package/audit/entities/entity-transaction.entity.js +33 -1
- package/audit/entities/index.d.ts +2 -0
- package/audit/entities/index.js +2 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +45 -5
- package/audit/enums/audit.enums.js +47 -4
- package/audit/index.d.ts +3 -1
- package/audit/index.js +30 -1
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +182 -2
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +129 -3
- package/audit/services/entity-audit.service.js +301 -6
- package/audit/services/index.d.ts +2 -0
- package/audit/services/index.js +2 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -4
- package/common/boilerplate.polyfill.js +24 -100
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +20 -5
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +78 -0
- package/redis-lock/lock-heartbeat.service.js +222 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +66 -0
- package/redis-lock/redis-lock.module.js +175 -70
- package/redis-lock/redis-lock.service.d.ts +278 -0
- package/redis-lock/redis-lock.service.js +282 -12
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +227 -0
- package/setup/schedule.decorator.js +235 -12
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +27 -14
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +134 -0
- package/validators/custom-validate.validator.js +214 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +32 -5
- package/validators/is-unique.validator.js +99 -17
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -26,33 +26,57 @@ const common_1 = require("@nestjs/common");
|
|
|
26
26
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
27
27
|
const typeorm_2 = require("typeorm");
|
|
28
28
|
const entities_1 = require("../entities");
|
|
29
|
+
/**
|
|
30
|
+
* 操作描述服务
|
|
31
|
+
* 负责根据模板和参数动态生成多语言描述
|
|
32
|
+
*/
|
|
29
33
|
let OperationDescriptionService = class OperationDescriptionService {
|
|
30
34
|
constructor(templateRepository, transactionRepository, auditLogRepository, manualOperationRepository) {
|
|
31
35
|
this.templateRepository = templateRepository;
|
|
32
36
|
this.transactionRepository = transactionRepository;
|
|
33
37
|
this.auditLogRepository = auditLogRepository;
|
|
34
38
|
this.manualOperationRepository = manualOperationRepository;
|
|
39
|
+
// 模板缓存
|
|
35
40
|
this.templateCache = new Map();
|
|
36
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 动态生成操作名称
|
|
44
|
+
* @param templateKey 模板键
|
|
45
|
+
* @param language 语言
|
|
46
|
+
* @returns 操作名称
|
|
47
|
+
*/
|
|
37
48
|
generateOperationName(templateKey_1) {
|
|
38
49
|
return __awaiter(this, arguments, void 0, function* (templateKey, language = 'zh') {
|
|
39
50
|
const template = yield this.getOperationTemplate(templateKey);
|
|
40
51
|
if (!template) {
|
|
41
|
-
return templateKey;
|
|
52
|
+
return templateKey; // 如果没有模板,返回模板键
|
|
42
53
|
}
|
|
43
54
|
return template.nameTemplates[language] || template.nameTemplates['zh'] || templateKey;
|
|
44
55
|
});
|
|
45
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* 动态生成操作描述
|
|
59
|
+
* @param templateKey 模板键
|
|
60
|
+
* @param descriptionParams 描述参数
|
|
61
|
+
* @param language 语言
|
|
62
|
+
* @returns 描述文本
|
|
63
|
+
*/
|
|
46
64
|
generateDescription(templateKey_1, descriptionParams_1) {
|
|
47
65
|
return __awaiter(this, arguments, void 0, function* (templateKey, descriptionParams, language = 'zh') {
|
|
48
66
|
const template = yield this.getOperationTemplate(templateKey);
|
|
49
67
|
if (!template) {
|
|
50
|
-
return templateKey;
|
|
68
|
+
return templateKey; // 如果没有模板,返回模板键
|
|
51
69
|
}
|
|
52
70
|
const templateStr = template.descriptionTemplates[language] || template.descriptionTemplates['zh'] || templateKey;
|
|
53
71
|
return this.fillTemplate(templateStr, descriptionParams);
|
|
54
72
|
});
|
|
55
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* 动态生成变更详情
|
|
76
|
+
* @param changeDetails 变更详情列表
|
|
77
|
+
* @param language 语言
|
|
78
|
+
* @returns 格式化的变更详情
|
|
79
|
+
*/
|
|
56
80
|
generateChangeDetails(changeDetails_1) {
|
|
57
81
|
return __awaiter(this, arguments, void 0, function* (changeDetails, language = 'zh') {
|
|
58
82
|
return changeDetails.map((detail) => {
|
|
@@ -67,22 +91,32 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
67
91
|
});
|
|
68
92
|
});
|
|
69
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* 获取事务描述(包含所有变更)
|
|
96
|
+
* @param transactionId 事务ID
|
|
97
|
+
* @param language 语言
|
|
98
|
+
* @returns 事务描述对象
|
|
99
|
+
*/
|
|
70
100
|
getTransactionDescription(transactionId_1) {
|
|
71
101
|
return __awaiter(this, arguments, void 0, function* (transactionId, language = 'zh') {
|
|
102
|
+
// 获取事务信息
|
|
72
103
|
const transaction = yield this.transactionRepository.findOne({
|
|
73
104
|
where: { id: transactionId },
|
|
74
105
|
});
|
|
75
106
|
if (!transaction) {
|
|
76
107
|
throw new Error(`Transaction ${transactionId} not found`);
|
|
77
108
|
}
|
|
109
|
+
// 获取事务的审计日志
|
|
78
110
|
const auditLogs = yield this.auditLogRepository.find({
|
|
79
111
|
where: { requestId: transactionId },
|
|
80
112
|
order: { createdAt: 'ASC' },
|
|
81
113
|
});
|
|
114
|
+
// 获取事务的手动操作记录
|
|
82
115
|
const manualOperations = yield this.manualOperationRepository.find({
|
|
83
116
|
where: { transactionId },
|
|
84
117
|
order: { createdAt: 'ASC' },
|
|
85
118
|
});
|
|
119
|
+
// 生成操作名称和描述
|
|
86
120
|
let operationName;
|
|
87
121
|
let description;
|
|
88
122
|
if (transaction.operationTemplateKey) {
|
|
@@ -90,6 +124,7 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
90
124
|
description = yield this.generateDescription(transaction.operationTemplateKey, transaction.descriptionParams || {}, language);
|
|
91
125
|
}
|
|
92
126
|
else {
|
|
127
|
+
// 如果没有事务级别的模板,使用第一个变更的模板
|
|
93
128
|
const firstLog = auditLogs[0];
|
|
94
129
|
if (firstLog && firstLog.operationTemplateKey) {
|
|
95
130
|
operationName = yield this.generateOperationName(firstLog.operationTemplateKey, language);
|
|
@@ -100,7 +135,9 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
100
135
|
description = transaction.description || 'Unknown operation';
|
|
101
136
|
}
|
|
102
137
|
}
|
|
138
|
+
// 生成变更详情
|
|
103
139
|
const changes = [];
|
|
140
|
+
// 添加实体变更
|
|
104
141
|
for (const log of auditLogs) {
|
|
105
142
|
const changeDescription = log.operationTemplateKey
|
|
106
143
|
? yield this.generateDescription(log.operationTemplateKey, log.descriptionParams || {}, language)
|
|
@@ -117,6 +154,7 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
117
154
|
createdAt: log.createdAt,
|
|
118
155
|
});
|
|
119
156
|
}
|
|
157
|
+
// 添加手动操作
|
|
120
158
|
for (const manualOp of manualOperations) {
|
|
121
159
|
const opName = yield this.generateOperationName(manualOp.operationTemplateKey, language);
|
|
122
160
|
const opDescription = yield this.generateDescription(manualOp.operationTemplateKey, manualOp.descriptionParams, language);
|
|
@@ -127,6 +165,7 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
127
165
|
createdAt: manualOp.createdAt,
|
|
128
166
|
});
|
|
129
167
|
}
|
|
168
|
+
// 按时间排序
|
|
130
169
|
changes.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
131
170
|
return {
|
|
132
171
|
operationName,
|
|
@@ -135,6 +174,12 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
135
174
|
};
|
|
136
175
|
});
|
|
137
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* 批量获取事务描述
|
|
179
|
+
* @param transactionIds 事务ID列表
|
|
180
|
+
* @param language 语言
|
|
181
|
+
* @returns 事务描述映射
|
|
182
|
+
*/
|
|
138
183
|
batchGetTransactionDescriptions(transactionIds_1) {
|
|
139
184
|
return __awaiter(this, arguments, void 0, function* (transactionIds, language = 'zh') {
|
|
140
185
|
const results = {};
|
|
@@ -143,16 +188,24 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
143
188
|
results[transactionId] = yield this.getTransactionDescription(transactionId, language);
|
|
144
189
|
}
|
|
145
190
|
catch (error) {
|
|
191
|
+
// 忽略错误,继续处理其他事务
|
|
146
192
|
console.error(`Failed to get description for transaction ${transactionId}:`, error);
|
|
147
193
|
}
|
|
148
194
|
}
|
|
149
195
|
return results;
|
|
150
196
|
});
|
|
151
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* 填充模板
|
|
200
|
+
* @param template 模板字符串
|
|
201
|
+
* @param params 参数
|
|
202
|
+
* @returns 填充后的字符串
|
|
203
|
+
*/
|
|
152
204
|
fillTemplate(template, params) {
|
|
153
205
|
if (!template)
|
|
154
206
|
return '';
|
|
155
207
|
let result = template;
|
|
208
|
+
// 替换参数 {key} -> value
|
|
156
209
|
for (const [key, value] of Object.entries(params || {})) {
|
|
157
210
|
const placeholder = `{${key}}`;
|
|
158
211
|
if (result.includes(placeholder)) {
|
|
@@ -161,6 +214,12 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
161
214
|
}
|
|
162
215
|
return result;
|
|
163
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* 格式化显示值
|
|
219
|
+
* @param value 原始值
|
|
220
|
+
* @param displayValue 显示值
|
|
221
|
+
* @returns 格式化后的值
|
|
222
|
+
*/
|
|
164
223
|
formatDisplayValue(value, displayValue) {
|
|
165
224
|
if (displayValue !== undefined) {
|
|
166
225
|
return displayValue;
|
|
@@ -170,23 +229,38 @@ let OperationDescriptionService = class OperationDescriptionService {
|
|
|
170
229
|
}
|
|
171
230
|
return String(value);
|
|
172
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* 获取操作模板(带缓存)
|
|
234
|
+
* @param templateKey 模板键
|
|
235
|
+
* @returns 操作模板
|
|
236
|
+
*/
|
|
173
237
|
getOperationTemplate(templateKey) {
|
|
174
238
|
return __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
// 检查缓存
|
|
175
240
|
if (this.templateCache.has(templateKey)) {
|
|
176
241
|
return this.templateCache.get(templateKey);
|
|
177
242
|
}
|
|
243
|
+
// 从数据库查询
|
|
178
244
|
const template = yield this.templateRepository.findOne({
|
|
179
245
|
where: { key: templateKey },
|
|
180
246
|
});
|
|
181
247
|
if (template) {
|
|
248
|
+
// 缓存模板
|
|
182
249
|
this.templateCache.set(templateKey, template);
|
|
183
250
|
}
|
|
184
251
|
return template;
|
|
185
252
|
});
|
|
186
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* 清除模板缓存
|
|
256
|
+
*/
|
|
187
257
|
clearTemplateCache() {
|
|
188
258
|
this.templateCache.clear();
|
|
189
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* 预加载模板到缓存
|
|
262
|
+
* @param templateKeys 模板键列表
|
|
263
|
+
*/
|
|
190
264
|
preloadTemplates(templateKeys) {
|
|
191
265
|
return __awaiter(this, void 0, void 0, function* () {
|
|
192
266
|
const templates = yield this.templateRepository
|
|
@@ -4,19 +4,49 @@ import { AuditOperation } from '../enums';
|
|
|
4
4
|
import { AuditContextService } from './audit-context.service';
|
|
5
5
|
import { EntityAuditService } from './entity-audit.service';
|
|
6
6
|
import { MultiDatabaseService } from './multi-database.service';
|
|
7
|
+
/**
|
|
8
|
+
* 事务审计服务
|
|
9
|
+
*/
|
|
7
10
|
export declare class TransactionAuditService {
|
|
8
11
|
private readonly transactionRepository;
|
|
9
12
|
private readonly contextService;
|
|
10
13
|
private readonly auditService;
|
|
11
14
|
private readonly multiDbService;
|
|
12
15
|
constructor(transactionRepository: Repository<EntityTransactionEntity>, contextService: AuditContextService, auditService: EntityAuditService, multiDbService: MultiDatabaseService);
|
|
16
|
+
/**
|
|
17
|
+
* 开始事务
|
|
18
|
+
*/
|
|
13
19
|
beginTransaction(description: string): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* 提交事务
|
|
22
|
+
*/
|
|
14
23
|
commitTransaction(transactionId: string): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 回滚事务(支持多数据库)
|
|
26
|
+
*/
|
|
15
27
|
rollbackTransaction(transactionId: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 添加实体到事务
|
|
30
|
+
*/
|
|
16
31
|
addEntityToTransaction(transactionId: string, entityType: string, entityId: string, operation: AuditOperation): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* 执行回滚(支持多数据库)
|
|
34
|
+
*/
|
|
17
35
|
private performRollback;
|
|
36
|
+
/**
|
|
37
|
+
* 按数据库连接分组实体
|
|
38
|
+
*/
|
|
18
39
|
private groupEntitiesByConnection;
|
|
40
|
+
/**
|
|
41
|
+
* 在指定连接中回滚实体
|
|
42
|
+
*/
|
|
19
43
|
private rollbackEntitiesInConnection;
|
|
44
|
+
/**
|
|
45
|
+
* 回滚单个实体
|
|
46
|
+
*/
|
|
20
47
|
private rollbackSingleEntity;
|
|
48
|
+
/**
|
|
49
|
+
* 获取最新的审计日志
|
|
50
|
+
*/
|
|
21
51
|
private getLatestAuditLog;
|
|
22
52
|
}
|
|
@@ -30,6 +30,9 @@ const enums_1 = require("../enums");
|
|
|
30
30
|
const audit_context_service_1 = require("./audit-context.service");
|
|
31
31
|
const entity_audit_service_1 = require("./entity-audit.service");
|
|
32
32
|
const multi_database_service_1 = require("./multi-database.service");
|
|
33
|
+
/**
|
|
34
|
+
* 事务审计服务
|
|
35
|
+
*/
|
|
33
36
|
let TransactionAuditService = class TransactionAuditService {
|
|
34
37
|
constructor(transactionRepository, contextService, auditService, multiDbService) {
|
|
35
38
|
this.transactionRepository = transactionRepository;
|
|
@@ -37,6 +40,9 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
37
40
|
this.auditService = auditService;
|
|
38
41
|
this.multiDbService = multiDbService;
|
|
39
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* 开始事务
|
|
45
|
+
*/
|
|
40
46
|
beginTransaction(description) {
|
|
41
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
48
|
const context = yield this.contextService.getCurrentContext();
|
|
@@ -48,12 +54,16 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
48
54
|
username: context.username,
|
|
49
55
|
});
|
|
50
56
|
const savedTransaction = yield this.transactionRepository.save(transaction);
|
|
57
|
+
// 设置事务ID到上下文
|
|
51
58
|
this.contextService.setContext({
|
|
52
59
|
transactionId: savedTransaction.id,
|
|
53
60
|
});
|
|
54
61
|
return savedTransaction.id;
|
|
55
62
|
});
|
|
56
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* 提交事务
|
|
66
|
+
*/
|
|
57
67
|
commitTransaction(transactionId) {
|
|
58
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
59
69
|
const transaction = yield this.transactionRepository.findOne({
|
|
@@ -66,6 +76,9 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
66
76
|
yield this.transactionRepository.save(transaction);
|
|
67
77
|
});
|
|
68
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* 回滚事务(支持多数据库)
|
|
81
|
+
*/
|
|
69
82
|
rollbackTransaction(transactionId) {
|
|
70
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
71
84
|
const transaction = yield this.transactionRepository.findOne({
|
|
@@ -74,11 +87,15 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
74
87
|
if (!transaction) {
|
|
75
88
|
throw new Error(`Transaction not found: ${transactionId}`);
|
|
76
89
|
}
|
|
90
|
+
// 执行回滚操作
|
|
77
91
|
yield this.performRollback(transaction);
|
|
78
92
|
transaction.status = enums_1.TransactionStatus.ROLLED_BACK;
|
|
79
93
|
yield this.transactionRepository.save(transaction);
|
|
80
94
|
});
|
|
81
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* 添加实体到事务
|
|
98
|
+
*/
|
|
82
99
|
addEntityToTransaction(transactionId, entityType, entityId, operation) {
|
|
83
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
101
|
const transaction = yield this.transactionRepository.findOne({
|
|
@@ -95,19 +112,30 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
95
112
|
yield this.transactionRepository.save(transaction);
|
|
96
113
|
});
|
|
97
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* 执行回滚(支持多数据库)
|
|
117
|
+
*/
|
|
98
118
|
performRollback(transaction) {
|
|
99
119
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
// 按相反顺序回滚实体
|
|
100
121
|
const reversedEntities = [...transaction.entities].reverse();
|
|
122
|
+
// 按数据库连接分组
|
|
101
123
|
const entitiesByConnection = yield this.groupEntitiesByConnection(reversedEntities);
|
|
124
|
+
// 对每个数据库连接执行回滚
|
|
102
125
|
for (const [connectionName, entities] of Object.entries(entitiesByConnection)) {
|
|
103
126
|
yield this.rollbackEntitiesInConnection(connectionName, entities);
|
|
104
127
|
}
|
|
105
128
|
});
|
|
106
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* 按数据库连接分组实体
|
|
132
|
+
*/
|
|
107
133
|
groupEntitiesByConnection(entities) {
|
|
108
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
135
|
const grouped = {};
|
|
136
|
+
// 获取所有监听的连接
|
|
110
137
|
const monitoredConnections = this.multiDbService.getMonitoredConnections();
|
|
138
|
+
// 尝试确定每个实体属于哪个连接
|
|
111
139
|
for (const entity of entities) {
|
|
112
140
|
let connectionFound = false;
|
|
113
141
|
for (const connectionName of monitoredConnections) {
|
|
@@ -124,9 +152,11 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
catch (error) {
|
|
155
|
+
// 继续尝试下一个连接
|
|
127
156
|
continue;
|
|
128
157
|
}
|
|
129
158
|
}
|
|
159
|
+
// 如果没有找到连接,使用默认连接
|
|
130
160
|
if (!connectionFound) {
|
|
131
161
|
const defaultConnection = 'default';
|
|
132
162
|
if (!grouped[defaultConnection]) {
|
|
@@ -138,9 +168,13 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
138
168
|
return grouped;
|
|
139
169
|
});
|
|
140
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* 在指定连接中回滚实体
|
|
173
|
+
*/
|
|
141
174
|
rollbackEntitiesInConnection(connectionName, entities) {
|
|
142
175
|
return __awaiter(this, void 0, void 0, function* () {
|
|
143
176
|
const dataSource = yield this.multiDbService.getDataSource(connectionName);
|
|
177
|
+
// 使用事务执行回滚
|
|
144
178
|
yield dataSource.transaction((manager) => __awaiter(this, void 0, void 0, function* () {
|
|
145
179
|
for (const entity of entities) {
|
|
146
180
|
try {
|
|
@@ -154,26 +188,34 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
154
188
|
}));
|
|
155
189
|
});
|
|
156
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* 回滚单个实体
|
|
193
|
+
*/
|
|
157
194
|
rollbackSingleEntity(manager, entity, connectionName) {
|
|
158
195
|
return __awaiter(this, void 0, void 0, function* () {
|
|
159
196
|
const repository = manager.getRepository(entity.entityType);
|
|
160
197
|
switch (entity.operation) {
|
|
161
198
|
case enums_1.AuditOperation.CREATE:
|
|
199
|
+
// 创建操作回滚:删除实体
|
|
162
200
|
yield repository.delete({ id: entity.entityId });
|
|
163
201
|
break;
|
|
164
202
|
case enums_1.AuditOperation.UPDATE:
|
|
203
|
+
// 更新操作回滚:恢复到之前的值
|
|
204
|
+
// 需要从审计日志中获取之前的值
|
|
165
205
|
const auditLog = yield this.getLatestAuditLog(entity.entityType, entity.entityId);
|
|
166
206
|
if (auditLog && auditLog.oldValue) {
|
|
167
207
|
yield repository.update({ id: entity.entityId }, auditLog.oldValue);
|
|
168
208
|
}
|
|
169
209
|
break;
|
|
170
210
|
case enums_1.AuditOperation.DELETE:
|
|
211
|
+
// 删除操作回滚:恢复实体
|
|
171
212
|
const deletedAuditLog = yield this.getLatestAuditLog(entity.entityType, entity.entityId);
|
|
172
213
|
if (deletedAuditLog && deletedAuditLog.oldValue) {
|
|
173
214
|
yield repository.save(deletedAuditLog.oldValue);
|
|
174
215
|
}
|
|
175
216
|
break;
|
|
176
217
|
case enums_1.AuditOperation.RESTORE:
|
|
218
|
+
// 恢复操作回滚:撤销恢复
|
|
177
219
|
const restoreAuditLog = yield this.getLatestAuditLog(entity.entityType, entity.entityId);
|
|
178
220
|
if (restoreAuditLog && restoreAuditLog.oldValue) {
|
|
179
221
|
yield repository.update({ id: entity.entityId }, restoreAuditLog.oldValue);
|
|
@@ -184,8 +226,13 @@ let TransactionAuditService = class TransactionAuditService {
|
|
|
184
226
|
}
|
|
185
227
|
});
|
|
186
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* 获取最新的审计日志
|
|
231
|
+
*/
|
|
187
232
|
getLatestAuditLog(entityType, entityId) {
|
|
188
233
|
return __awaiter(this, void 0, void 0, function* () {
|
|
234
|
+
// 这里需要从审计服务获取
|
|
235
|
+
// 由于循环依赖,这里简化实现
|
|
189
236
|
return null;
|
|
190
237
|
});
|
|
191
238
|
}
|
|
@@ -2,13 +2,28 @@ import { EntitySubscriberInterface, InsertEvent, UpdateEvent, RemoveEvent, DataS
|
|
|
2
2
|
import { EntityAuditService } from '../services/entity-audit.service';
|
|
3
3
|
import { AuditContextService } from '../services/audit-context.service';
|
|
4
4
|
import { DefaultAuditStrategy } from '../services/audit-strategy.service';
|
|
5
|
+
/**
|
|
6
|
+
* 实体审计订阅者
|
|
7
|
+
*/
|
|
5
8
|
export declare class EntityAuditSubscriber implements EntitySubscriberInterface<any> {
|
|
6
9
|
private readonly entityAuditService;
|
|
7
10
|
private readonly contextService;
|
|
8
11
|
private readonly auditStrategy;
|
|
9
12
|
constructor(entityAuditService: EntityAuditService, contextService: AuditContextService, auditStrategy: DefaultAuditStrategy, dataSource: DataSource);
|
|
13
|
+
/**
|
|
14
|
+
* 在实体插入后记录审计日志
|
|
15
|
+
*/
|
|
10
16
|
afterInsert(event: InsertEvent<any>): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* 在实体更新后记录审计日志
|
|
19
|
+
*/
|
|
11
20
|
afterUpdate(event: UpdateEvent<any>): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* 在实体删除前记录审计日志
|
|
23
|
+
*/
|
|
12
24
|
beforeRemove(event: RemoveEvent<any>): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* 检查是否启用了审计
|
|
27
|
+
*/
|
|
13
28
|
private isAuditEnabled;
|
|
14
29
|
}
|
|
@@ -26,6 +26,9 @@ const audit_context_service_1 = require("../services/audit-context.service");
|
|
|
26
26
|
const audit_strategy_service_1 = require("../services/audit-strategy.service");
|
|
27
27
|
const enums_1 = require("../enums");
|
|
28
28
|
const decorators_1 = require("../decorators");
|
|
29
|
+
/**
|
|
30
|
+
* 实体审计订阅者
|
|
31
|
+
*/
|
|
29
32
|
let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
30
33
|
constructor(entityAuditService, contextService, auditStrategy, dataSource) {
|
|
31
34
|
this.entityAuditService = entityAuditService;
|
|
@@ -33,6 +36,9 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
33
36
|
this.auditStrategy = auditStrategy;
|
|
34
37
|
dataSource.subscribers.push(this);
|
|
35
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* 在实体插入后记录审计日志
|
|
41
|
+
*/
|
|
36
42
|
afterInsert(event) {
|
|
37
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
44
|
const entity = event.entity;
|
|
@@ -40,14 +46,18 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
40
46
|
return;
|
|
41
47
|
const entityType = entity.constructor.name;
|
|
42
48
|
const entityId = entity.id;
|
|
49
|
+
// 检查是否启用了审计
|
|
43
50
|
if (!this.isAuditEnabled(entity)) {
|
|
44
51
|
return;
|
|
45
52
|
}
|
|
53
|
+
// 检查策略
|
|
46
54
|
if (!this.auditStrategy.shouldRecord(entityType, enums_1.AuditOperation.CREATE)) {
|
|
47
55
|
return;
|
|
48
56
|
}
|
|
49
57
|
try {
|
|
58
|
+
// 获取上下文信息
|
|
50
59
|
const context = yield this.contextService.getCurrentContext();
|
|
60
|
+
// 记录审计日志
|
|
51
61
|
yield this.entityAuditService.logEntityChange(entityType, entityId, enums_1.AuditOperation.CREATE, {}, entity, {
|
|
52
62
|
requestId: context.requestId,
|
|
53
63
|
requestIp: context.requestIp,
|
|
@@ -59,6 +69,9 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
59
69
|
}
|
|
60
70
|
});
|
|
61
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 在实体更新后记录审计日志
|
|
74
|
+
*/
|
|
62
75
|
afterUpdate(event) {
|
|
63
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
77
|
const entity = event.entity;
|
|
@@ -67,14 +80,18 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
67
80
|
return;
|
|
68
81
|
const entityType = entity.constructor.name;
|
|
69
82
|
const entityId = entity.id;
|
|
83
|
+
// 检查是否启用了审计
|
|
70
84
|
if (!this.isAuditEnabled(entity)) {
|
|
71
85
|
return;
|
|
72
86
|
}
|
|
87
|
+
// 检查策略
|
|
73
88
|
if (!this.auditStrategy.shouldRecord(entityType, enums_1.AuditOperation.UPDATE)) {
|
|
74
89
|
return;
|
|
75
90
|
}
|
|
76
91
|
try {
|
|
92
|
+
// 获取上下文信息
|
|
77
93
|
const context = yield this.contextService.getCurrentContext();
|
|
94
|
+
// 记录审计日志
|
|
78
95
|
yield this.entityAuditService.logEntityChange(entityType, entityId, enums_1.AuditOperation.UPDATE, databaseEntity || {}, entity, {
|
|
79
96
|
requestId: context.requestId,
|
|
80
97
|
requestIp: context.requestIp,
|
|
@@ -86,6 +103,9 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
86
103
|
}
|
|
87
104
|
});
|
|
88
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* 在实体删除前记录审计日志
|
|
108
|
+
*/
|
|
89
109
|
beforeRemove(event) {
|
|
90
110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
111
|
const entity = event.entity;
|
|
@@ -93,14 +113,18 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
93
113
|
return;
|
|
94
114
|
const entityType = entity.constructor.name;
|
|
95
115
|
const entityId = entity.id;
|
|
116
|
+
// 检查是否启用了审计
|
|
96
117
|
if (!this.isAuditEnabled(entity)) {
|
|
97
118
|
return;
|
|
98
119
|
}
|
|
120
|
+
// 检查策略
|
|
99
121
|
if (!this.auditStrategy.shouldRecord(entityType, enums_1.AuditOperation.DELETE)) {
|
|
100
122
|
return;
|
|
101
123
|
}
|
|
102
124
|
try {
|
|
125
|
+
// 获取上下文信息
|
|
103
126
|
const context = yield this.contextService.getCurrentContext();
|
|
127
|
+
// 记录审计日志
|
|
104
128
|
yield this.entityAuditService.logEntityChange(entityType, entityId, enums_1.AuditOperation.DELETE, entity, {}, {
|
|
105
129
|
requestId: context.requestId,
|
|
106
130
|
requestIp: context.requestIp,
|
|
@@ -112,8 +136,12 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
112
136
|
}
|
|
113
137
|
});
|
|
114
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* 检查是否启用了审计
|
|
141
|
+
*/
|
|
115
142
|
isAuditEnabled(entity) {
|
|
116
143
|
try {
|
|
144
|
+
// 检查装饰器
|
|
117
145
|
const auditOptions = Reflect.getMetadata(decorators_1.ENTITY_AUDIT_OPTIONS, entity.constructor);
|
|
118
146
|
if (auditOptions && auditOptions.enabled === false) {
|
|
119
147
|
return false;
|
|
@@ -121,7 +149,7 @@ let EntityAuditSubscriber = class EntityAuditSubscriber {
|
|
|
121
149
|
return true;
|
|
122
150
|
}
|
|
123
151
|
catch (error) {
|
|
124
|
-
return true;
|
|
152
|
+
return true; // 默认启用
|
|
125
153
|
}
|
|
126
154
|
}
|
|
127
155
|
};
|