@dofe/infra-shared-services 0.1.1

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 (153) hide show
  1. package/dist/email/dto/email.dto.d.ts +70 -0
  2. package/dist/email/dto/email.dto.d.ts.map +1 -0
  3. package/dist/email/dto/email.dto.js +58 -0
  4. package/dist/email/dto/email.dto.js.map +1 -0
  5. package/dist/email/email.module.d.ts +3 -0
  6. package/dist/email/email.module.d.ts.map +1 -0
  7. package/dist/email/email.module.js +38 -0
  8. package/dist/email/email.module.js.map +1 -0
  9. package/dist/email/email.service.d.ts +61 -0
  10. package/dist/email/email.service.d.ts.map +1 -0
  11. package/dist/email/email.service.js +191 -0
  12. package/dist/email/email.service.js.map +1 -0
  13. package/dist/email/index.d.ts +5 -0
  14. package/dist/email/index.d.ts.map +1 -0
  15. package/dist/email/index.js +26 -0
  16. package/dist/email/index.js.map +1 -0
  17. package/dist/file-storage/bucket-resolver.d.ts +174 -0
  18. package/dist/file-storage/bucket-resolver.d.ts.map +1 -0
  19. package/dist/file-storage/bucket-resolver.js +270 -0
  20. package/dist/file-storage/bucket-resolver.js.map +1 -0
  21. package/dist/file-storage/file-storage.factory.d.ts +183 -0
  22. package/dist/file-storage/file-storage.factory.d.ts.map +1 -0
  23. package/dist/file-storage/file-storage.factory.js +300 -0
  24. package/dist/file-storage/file-storage.factory.js.map +1 -0
  25. package/dist/file-storage/file-storage.module.d.ts +49 -0
  26. package/dist/file-storage/file-storage.module.d.ts.map +1 -0
  27. package/dist/file-storage/file-storage.module.js +74 -0
  28. package/dist/file-storage/file-storage.module.js.map +1 -0
  29. package/dist/file-storage/file-storage.service.d.ts +381 -0
  30. package/dist/file-storage/file-storage.service.d.ts.map +1 -0
  31. package/dist/file-storage/file-storage.service.js +598 -0
  32. package/dist/file-storage/file-storage.service.js.map +1 -0
  33. package/dist/file-storage/index.d.ts +43 -0
  34. package/dist/file-storage/index.d.ts.map +1 -0
  35. package/dist/file-storage/index.js +65 -0
  36. package/dist/file-storage/index.js.map +1 -0
  37. package/dist/file-storage/types.d.ts +187 -0
  38. package/dist/file-storage/types.d.ts.map +1 -0
  39. package/dist/file-storage/types.js +21 -0
  40. package/dist/file-storage/types.js.map +1 -0
  41. package/dist/index.d.ts +20 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +35 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/ip-geo/continent-mapping.d.ts +31 -0
  46. package/dist/ip-geo/continent-mapping.d.ts.map +1 -0
  47. package/dist/ip-geo/continent-mapping.js +246 -0
  48. package/dist/ip-geo/continent-mapping.js.map +1 -0
  49. package/dist/ip-geo/index.d.ts +33 -0
  50. package/dist/ip-geo/index.d.ts.map +1 -0
  51. package/dist/ip-geo/index.js +41 -0
  52. package/dist/ip-geo/index.js.map +1 -0
  53. package/dist/ip-geo/ip-geo.module.d.ts +8 -0
  54. package/dist/ip-geo/ip-geo.module.d.ts.map +1 -0
  55. package/dist/ip-geo/ip-geo.module.js +34 -0
  56. package/dist/ip-geo/ip-geo.module.js.map +1 -0
  57. package/dist/ip-geo/ip-geo.service.d.ts +43 -0
  58. package/dist/ip-geo/ip-geo.service.d.ts.map +1 -0
  59. package/dist/ip-geo/ip-geo.service.js +153 -0
  60. package/dist/ip-geo/ip-geo.service.js.map +1 -0
  61. package/dist/ip-info/index.d.ts +7 -0
  62. package/dist/ip-info/index.d.ts.map +1 -0
  63. package/dist/ip-info/index.js +13 -0
  64. package/dist/ip-info/index.js.map +1 -0
  65. package/dist/ip-info/ip-info.client.d.ts +32 -0
  66. package/dist/ip-info/ip-info.client.d.ts.map +1 -0
  67. package/dist/ip-info/ip-info.client.js +73 -0
  68. package/dist/ip-info/ip-info.client.js.map +1 -0
  69. package/dist/ip-info/ip-info.module.d.ts +3 -0
  70. package/dist/ip-info/ip-info.module.d.ts.map +1 -0
  71. package/dist/ip-info/ip-info.module.js +45 -0
  72. package/dist/ip-info/ip-info.module.js.map +1 -0
  73. package/dist/ip-info/ip-info.service.d.ts +50 -0
  74. package/dist/ip-info/ip-info.service.d.ts.map +1 -0
  75. package/dist/ip-info/ip-info.service.js +177 -0
  76. package/dist/ip-info/ip-info.service.js.map +1 -0
  77. package/dist/ocr/index.d.ts +33 -0
  78. package/dist/ocr/index.d.ts.map +1 -0
  79. package/dist/ocr/index.js +53 -0
  80. package/dist/ocr/index.js.map +1 -0
  81. package/dist/ocr/ocr.module.d.ts +41 -0
  82. package/dist/ocr/ocr.module.d.ts.map +1 -0
  83. package/dist/ocr/ocr.module.js +61 -0
  84. package/dist/ocr/ocr.module.js.map +1 -0
  85. package/dist/ocr/ocr.service.d.ts +111 -0
  86. package/dist/ocr/ocr.service.d.ts.map +1 -0
  87. package/dist/ocr/ocr.service.js +214 -0
  88. package/dist/ocr/ocr.service.js.map +1 -0
  89. package/dist/sms/index.d.ts +5 -0
  90. package/dist/sms/index.d.ts.map +1 -0
  91. package/dist/sms/index.js +29 -0
  92. package/dist/sms/index.js.map +1 -0
  93. package/dist/sms/sms.factory.d.ts +140 -0
  94. package/dist/sms/sms.factory.d.ts.map +1 -0
  95. package/dist/sms/sms.factory.js +276 -0
  96. package/dist/sms/sms.factory.js.map +1 -0
  97. package/dist/sms/sms.module.d.ts +3 -0
  98. package/dist/sms/sms.module.d.ts.map +1 -0
  99. package/dist/sms/sms.module.js +38 -0
  100. package/dist/sms/sms.module.js.map +1 -0
  101. package/dist/sms/sms.service.d.ts +139 -0
  102. package/dist/sms/sms.service.d.ts.map +1 -0
  103. package/dist/sms/sms.service.js +278 -0
  104. package/dist/sms/sms.service.js.map +1 -0
  105. package/dist/sms/types.d.ts +204 -0
  106. package/dist/sms/types.d.ts.map +1 -0
  107. package/dist/sms/types.js +44 -0
  108. package/dist/sms/types.js.map +1 -0
  109. package/dist/streaming-asr/index.d.ts +45 -0
  110. package/dist/streaming-asr/index.d.ts.map +1 -0
  111. package/dist/streaming-asr/index.js +66 -0
  112. package/dist/streaming-asr/index.js.map +1 -0
  113. package/dist/streaming-asr/streaming-asr.module.d.ts +37 -0
  114. package/dist/streaming-asr/streaming-asr.module.d.ts.map +1 -0
  115. package/dist/streaming-asr/streaming-asr.module.js +59 -0
  116. package/dist/streaming-asr/streaming-asr.module.js.map +1 -0
  117. package/dist/streaming-asr/streaming-asr.service.d.ts +276 -0
  118. package/dist/streaming-asr/streaming-asr.service.d.ts.map +1 -0
  119. package/dist/streaming-asr/streaming-asr.service.js +1120 -0
  120. package/dist/streaming-asr/streaming-asr.service.js.map +1 -0
  121. package/dist/streaming-asr/types.d.ts +194 -0
  122. package/dist/streaming-asr/types.d.ts.map +1 -0
  123. package/dist/streaming-asr/types.js +8 -0
  124. package/dist/streaming-asr/types.js.map +1 -0
  125. package/dist/system-health/index.d.ts +7 -0
  126. package/dist/system-health/index.d.ts.map +1 -0
  127. package/dist/system-health/index.js +25 -0
  128. package/dist/system-health/index.js.map +1 -0
  129. package/dist/system-health/system-health.controller.d.ts +43 -0
  130. package/dist/system-health/system-health.controller.d.ts.map +1 -0
  131. package/dist/system-health/system-health.controller.js +86 -0
  132. package/dist/system-health/system-health.controller.js.map +1 -0
  133. package/dist/system-health/system-health.module.d.ts +3 -0
  134. package/dist/system-health/system-health.module.d.ts.map +1 -0
  135. package/dist/system-health/system-health.module.js +29 -0
  136. package/dist/system-health/system-health.module.js.map +1 -0
  137. package/dist/system-health/system-health.service.d.ts +14 -0
  138. package/dist/system-health/system-health.service.d.ts.map +1 -0
  139. package/dist/system-health/system-health.service.js +87 -0
  140. package/dist/system-health/system-health.service.js.map +1 -0
  141. package/dist/uploader/index.d.ts +3 -0
  142. package/dist/uploader/index.d.ts.map +1 -0
  143. package/dist/uploader/index.js +8 -0
  144. package/dist/uploader/index.js.map +1 -0
  145. package/dist/uploader/uploader.module.d.ts +3 -0
  146. package/dist/uploader/uploader.module.d.ts.map +1 -0
  147. package/dist/uploader/uploader.module.js +25 -0
  148. package/dist/uploader/uploader.module.js.map +1 -0
  149. package/dist/uploader/uploader.service.d.ts +86 -0
  150. package/dist/uploader/uploader.service.d.ts.map +1 -0
  151. package/dist/uploader/uploader.service.js +188 -0
  152. package/dist/uploader/uploader.service.js.map +1 -0
  153. package/package.json +51 -0
@@ -0,0 +1,214 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.OcrService = void 0;
16
+ /**
17
+ * OCR Service
18
+ *
19
+ * 职责:通过 AgentX 任务 API 调用 OCR 服务
20
+ * - 使用 agent_x.tasks.ocr.ocr_parse_task 进行单文件 OCR
21
+ * - 使用 agent_x.tasks.ocr.ocr_parse_batch_task 进行批量 OCR
22
+ * - 支持同步等待和回调两种模式
23
+ */
24
+ const common_1 = require("@nestjs/common");
25
+ const nest_winston_1 = require("nest-winston");
26
+ const winston_1 = require("winston");
27
+ const infra_clients_1 = require("@dofe/infra-clients");
28
+ /** OCR 任务名称 */
29
+ const OCR_PARSE_TASK = 'agent_x.tasks.ocr.ocr_parse_task';
30
+ const OCR_PARSE_BATCH_TASK = 'agent_x.tasks.ocr.ocr_parse_batch_task';
31
+ /**
32
+ * OCR 服务
33
+ *
34
+ * 封装与 Python OCR 服务的交互,通过 AgentX 任务队列执行
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // 注入服务
39
+ * @Injectable()
40
+ * class MyService {
41
+ * constructor(private readonly ocrService: OcrService) {}
42
+ *
43
+ * async extractText(fileUrl: string) {
44
+ * const result = await this.ocrService.extractText(fileUrl, 'pdf');
45
+ * return result.text;
46
+ * }
47
+ * }
48
+ * ```
49
+ */
50
+ let OcrService = class OcrService {
51
+ logger;
52
+ agentxClient;
53
+ constructor(logger, agentxClient) {
54
+ this.logger = logger;
55
+ this.agentxClient = agentxClient;
56
+ }
57
+ /**
58
+ * 提取文件文本内容
59
+ *
60
+ * 流程:
61
+ * 1. 创建 OCR 任务
62
+ * 2. 等待任务完成(使用 SSE 或轮询)
63
+ * 3. 返回提取的文本
64
+ *
65
+ * @param fileUrl 文件 URL (必须是可访问的 URL)
66
+ * @param fileType 文件类型 (pdf, docx, doc, png, jpg, jpeg, etc.)
67
+ * @param options 可选参数
68
+ */
69
+ async extractText(fileUrl, fileType, options) {
70
+ this.logger.info('创建 OCR 任务', {
71
+ fileUrl: fileUrl.substring(0, 100),
72
+ fileType,
73
+ mode: options?.mode || 'basic',
74
+ });
75
+ try {
76
+ // 1. 构建任务参数
77
+ const taskParams = {
78
+ file_url: fileUrl,
79
+ mode: options?.mode || 'basic',
80
+ enable_cache: options?.enable_cache ?? true,
81
+ };
82
+ if (options?.custom_prompt) {
83
+ taskParams.custom_prompt = options.custom_prompt;
84
+ }
85
+ // 2. 创建 OCR 任务
86
+ const taskId = await this.agentxClient.createTask({
87
+ name: OCR_PARSE_TASK,
88
+ params: taskParams,
89
+ });
90
+ this.logger.info('OCR 任务已创建,等待完成', {
91
+ taskId,
92
+ taskName: OCR_PARSE_TASK,
93
+ });
94
+ // 3. 等待任务完成(使用 AgentX 的 SSE 或轮询)
95
+ const status = await this.agentxClient.monitorTaskWithSSE(taskId);
96
+ // 4. 检查任务结果
97
+ if (status.state !== 'SUCCESS' || !status.result) {
98
+ throw new Error(status.error || 'OCR task failed');
99
+ }
100
+ // AgentX 返回的结果是嵌套结构: status.result.result
101
+ const taskResult = status.result;
102
+ const result = taskResult.result || taskResult;
103
+ // 5. 转换结果格式
104
+ const ocrResult = {
105
+ text: result.raw_text || result.text || '',
106
+ confidence: result.confidence || 0,
107
+ fileType: fileType,
108
+ processingTime: result.processing_time,
109
+ };
110
+ if (result.pages && options?.extractPages) {
111
+ ocrResult.pages = result.pages.map((p) => ({
112
+ pageNumber: p.pageNumber,
113
+ text: p.text,
114
+ }));
115
+ }
116
+ this.logger.info('OCR 任务完成', {
117
+ taskId,
118
+ textLength: ocrResult.text.length,
119
+ confidence: ocrResult.confidence,
120
+ });
121
+ return ocrResult;
122
+ }
123
+ catch (error) {
124
+ this.logger.error('OCR 文本提取失败', {
125
+ fileUrl: fileUrl.substring(0, 100),
126
+ fileType,
127
+ error: error instanceof Error ? error.message : 'Unknown error',
128
+ });
129
+ throw new Error(`OCR extraction failed: ${error.message}`);
130
+ }
131
+ }
132
+ /**
133
+ * 批量提取文件文本
134
+ *
135
+ * @param files 文件列表
136
+ * @param options 可选参数
137
+ */
138
+ async extractTextBatch(files, options) {
139
+ this.logger.info('创建批量 OCR 任务', {
140
+ fileCount: files.length,
141
+ mode: options?.mode || 'basic',
142
+ });
143
+ try {
144
+ // 1. 构建批量任务参数
145
+ const taskParams = {
146
+ file_urls: files.map((f) => f.fileUrl),
147
+ mode: options?.mode || 'basic',
148
+ enable_cache: true,
149
+ max_parallel: options?.max_parallel || 3,
150
+ };
151
+ // 2. 创建批量 OCR 任务
152
+ const taskId = await this.agentxClient.createTask({
153
+ name: OCR_PARSE_BATCH_TASK,
154
+ params: taskParams,
155
+ });
156
+ this.logger.info('批量 OCR 任务已创建,等待完成', {
157
+ taskId,
158
+ fileCount: files.length,
159
+ });
160
+ // 3. 等待任务完成
161
+ const status = await this.agentxClient.monitorTaskWithSSE(taskId);
162
+ // 4. 检查任务结果
163
+ if (status.state !== 'SUCCESS' || !status.result) {
164
+ throw new Error(status.error || 'Batch OCR task failed');
165
+ }
166
+ // AgentX 返回的结果是嵌套结构: status.result.result
167
+ const taskResult = status.result;
168
+ const rawResults = taskResult.result || taskResult;
169
+ // 批量任务结果是一个数组
170
+ const results = Array.isArray(rawResults)
171
+ ? rawResults
172
+ : [rawResults];
173
+ this.logger.info('批量 OCR 任务完成', {
174
+ taskId,
175
+ resultCount: results.length,
176
+ });
177
+ // 5. 转换结果格式
178
+ return results.map((result, index) => {
179
+ if ('error' in result) {
180
+ return {
181
+ error: result.error,
182
+ fileUrl: files[index].fileUrl,
183
+ };
184
+ }
185
+ return {
186
+ text: result.raw_text || result.text || '',
187
+ confidence: result.confidence || 0,
188
+ fileType: files[index].fileType,
189
+ };
190
+ });
191
+ }
192
+ catch (error) {
193
+ this.logger.error('批量 OCR 文本提取失败', {
194
+ fileCount: files.length,
195
+ error: error instanceof Error ? error.message : 'Unknown error',
196
+ });
197
+ throw new Error(`OCR batch extraction failed: ${error.message}`);
198
+ }
199
+ }
200
+ /**
201
+ * 检查 OCR 服务健康状态
202
+ */
203
+ async healthCheck() {
204
+ return this.agentxClient.healthCheck();
205
+ }
206
+ };
207
+ exports.OcrService = OcrService;
208
+ exports.OcrService = OcrService = __decorate([
209
+ (0, common_1.Injectable)(),
210
+ __param(0, (0, common_1.Inject)(nest_winston_1.WINSTON_MODULE_PROVIDER)),
211
+ __metadata("design:paramtypes", [winston_1.Logger,
212
+ infra_clients_1.AgentXClient])
213
+ ], OcrService);
214
+ //# sourceMappingURL=ocr.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ocr.service.js","sourceRoot":"","sources":["../../src/ocr/ocr.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { SmsServiceModule } from './sms.module';
2
+ export { SmsService } from './sms.service';
3
+ export { SmsClientFactory } from './sms.factory';
4
+ export * from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sms/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,cAAc,SAAS,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.SmsClientFactory = exports.SmsService = exports.SmsServiceModule = void 0;
18
+ // Module
19
+ var sms_module_1 = require("./sms.module");
20
+ Object.defineProperty(exports, "SmsServiceModule", { enumerable: true, get: function () { return sms_module_1.SmsServiceModule; } });
21
+ // Service
22
+ var sms_service_1 = require("./sms.service");
23
+ Object.defineProperty(exports, "SmsService", { enumerable: true, get: function () { return sms_service_1.SmsService; } });
24
+ // Factory
25
+ var sms_factory_1 = require("./sms.factory");
26
+ Object.defineProperty(exports, "SmsClientFactory", { enumerable: true, get: function () { return sms_factory_1.SmsClientFactory; } });
27
+ // Types (从 types.ts 导出,包含来自 @dofe/infra-clients 的 re-exports)
28
+ __exportStar(require("./types"), exports);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sms/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS;AACT,2CAAgD;AAAvC,8GAAA,gBAAgB,OAAA;AAEzB,UAAU;AACV,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AAEnB,UAAU;AACV,6CAAiD;AAAxC,+GAAA,gBAAgB,OAAA;AAEzB,8DAA8D;AAC9D,0CAAwB"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @fileoverview SMS Client Factory
3
+ * @module @app/shared-services/sms/sms.factory
4
+ *
5
+ * 负责创建和管理 SMS 客户端实例
6
+ *
7
+ * 功能:
8
+ * - 根据供应商类型创建对应的 SMS 客户端
9
+ * - 管理模板配置
10
+ * - 提供统一的客户端访问接口
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const factory = new SmsClientFactory(
15
+ * { logger, httpService, redis },
16
+ * { defaultVendor: 'volcengine', providers: [...] }
17
+ * );
18
+ *
19
+ * // 发送短信
20
+ * await factory.sendSmsCode('13800138000', '123456', 'verify');
21
+ *
22
+ * // 火山引擎专用:验证码校验
23
+ * const result = await factory.checkVerifyCode('13800138000', '123456');
24
+ * ```
25
+ */
26
+ import { SmsVendor, SmsTemplate, SmsTemplateMeta, SmsClientDependencies, SmsFactoryConfig, SmsSendResult, VerifyCodeCheckResult } from './types';
27
+ /**
28
+ * SMS 客户端工厂
29
+ *
30
+ * 负责创建和管理不同供应商的 SMS 客户端
31
+ */
32
+ export declare class SmsClientFactory {
33
+ /** 当前供应商配置 */
34
+ private readonly provider;
35
+ /** 当前供应商类型 */
36
+ private readonly vendor;
37
+ /** SMS 客户端实例 */
38
+ private readonly client;
39
+ /** 模板配置映射 */
40
+ private readonly templates;
41
+ /** 日志器 */
42
+ private readonly logger;
43
+ /** HTTP 服务 */
44
+ private readonly httpService?;
45
+ /** Redis 服务 */
46
+ private readonly redis?;
47
+ constructor(dependencies: SmsClientDependencies, config?: SmsFactoryConfig);
48
+ /**
49
+ * 从配置初始化
50
+ */
51
+ private initializeFromConfig;
52
+ /**
53
+ * 初始化模板配置
54
+ */
55
+ private initializeTemplates;
56
+ /**
57
+ * 创建 SMS 客户端
58
+ */
59
+ private createClient;
60
+ /**
61
+ * 检查工厂是否已初始化
62
+ */
63
+ get isInitialized(): boolean;
64
+ /**
65
+ * 获取当前供应商类型
66
+ */
67
+ get currentVendor(): SmsVendor | null;
68
+ /**
69
+ * 获取当前供应商显示名称
70
+ */
71
+ get currentVendorName(): string;
72
+ /**
73
+ * 检查是否为火山引擎供应商
74
+ */
75
+ get isVolcengine(): boolean;
76
+ /**
77
+ * 获取所有模板名称
78
+ */
79
+ get templateNames(): string[];
80
+ /**
81
+ * 获取模板配置
82
+ *
83
+ * @param templateId - 模板 ID
84
+ * @returns 模板配置,不存在返回 undefined
85
+ */
86
+ getTemplate(templateId: string): SmsTemplate | undefined;
87
+ /**
88
+ * 获取模板配置(必须存在)
89
+ *
90
+ * @param templateId - 模板 ID
91
+ * @throws Error 如果模板不存在
92
+ */
93
+ getTemplateOrThrow(templateId: string): SmsTemplate;
94
+ /**
95
+ * 获取模板元数据
96
+ *
97
+ * @param templateId - 模板 ID
98
+ * @returns 模板元数据
99
+ */
100
+ getTemplateMeta(templateId: string): SmsTemplateMeta | undefined;
101
+ /**
102
+ * 发送短信验证码
103
+ *
104
+ * @param phone - 手机号码
105
+ * @param code - 验证码
106
+ * @param templateId - 模板 ID
107
+ * @returns 发送结果
108
+ */
109
+ sendSmsCode(phone: string, code: string, templateId?: string): Promise<SmsSendResult>;
110
+ /**
111
+ * 发送验证码(火山引擎自动生成)
112
+ *
113
+ * 仅火山引擎供应商支持此功能
114
+ *
115
+ * @param phoneNumber - 手机号码
116
+ * @param templateId - 模板 ID
117
+ * @throws Error 如果当前供应商不是火山引擎
118
+ */
119
+ sendVerifyCode(phoneNumber: string, templateId?: string): Promise<any>;
120
+ /**
121
+ * 校验验证码(火山引擎)
122
+ *
123
+ * 仅火山引擎供应商支持此功能
124
+ *
125
+ * @param phoneNumber - 手机号码
126
+ * @param code - 验证码
127
+ * @param templateId - 模板 ID
128
+ * @throws Error 如果当前供应商不是火山引擎
129
+ */
130
+ checkVerifyCode(phoneNumber: string, code: string, templateId?: string): Promise<VerifyCodeCheckResult>;
131
+ /**
132
+ * 确保工厂已初始化
133
+ */
134
+ private ensureInitialized;
135
+ /**
136
+ * 确保当前供应商为火山引擎
137
+ */
138
+ private ensureVolcengine;
139
+ }
140
+ //# sourceMappingURL=sms.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sms.factory.d.ts","sourceRoot":"","sources":["../../src/sms/sms.factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAcH,OAAO,EACL,SAAS,EAET,WAAW,EACX,eAAe,EAIf,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AAOjB;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IAEjD,gBAAgB;IAChB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAElD,aAAa;IACb,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAEhD,UAAU;IACV,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAE3C,eAAe;IACf,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAe;gBAE1B,YAAY,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAU1E;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,YAAY;IA2CpB;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,SAAS,GAAG,IAAI,CAEpC;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAMD;;;;;OAKG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxD;;;;;OAKG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW;IAQnD;;;;;OAKG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAehE;;;;;;;OAOG;IACG,WAAW,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAiB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAazB;;;;;;;;OAQG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAAiB,GAC5B,OAAO,CAAC,GAAG,CAAC;IAcf;;;;;;;;;OASG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAiB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAmBjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAKzB"}
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview SMS Client Factory
4
+ * @module @app/shared-services/sms/sms.factory
5
+ *
6
+ * 负责创建和管理 SMS 客户端实例
7
+ *
8
+ * 功能:
9
+ * - 根据供应商类型创建对应的 SMS 客户端
10
+ * - 管理模板配置
11
+ * - 提供统一的客户端访问接口
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const factory = new SmsClientFactory(
16
+ * { logger, httpService, redis },
17
+ * { defaultVendor: 'volcengine', providers: [...] }
18
+ * );
19
+ *
20
+ * // 发送短信
21
+ * await factory.sendSmsCode('13800138000', '123456', 'verify');
22
+ *
23
+ * // 火山引擎专用:验证码校验
24
+ * const result = await factory.checkVerifyCode('13800138000', '123456');
25
+ * ```
26
+ */
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.SmsClientFactory = void 0;
32
+ const infra_clients_1 = require("@dofe/infra-clients");
33
+ const types_1 = require("./types");
34
+ const environment_util_1 = __importDefault(require("@dofe/infra-utils/environment.util"));
35
+ // ============================================================================
36
+ // SMS Client Factory
37
+ // ============================================================================
38
+ /**
39
+ * SMS 客户端工厂
40
+ *
41
+ * 负责创建和管理不同供应商的 SMS 客户端
42
+ */
43
+ class SmsClientFactory {
44
+ /** 当前供应商配置 */
45
+ provider = null;
46
+ /** 当前供应商类型 */
47
+ vendor = null;
48
+ /** SMS 客户端实例 */
49
+ client = null;
50
+ /** 模板配置映射 */
51
+ templates = {};
52
+ /** 日志器 */
53
+ logger;
54
+ /** HTTP 服务 */
55
+ httpService;
56
+ /** Redis 服务 */
57
+ redis;
58
+ constructor(dependencies, config) {
59
+ this.logger = dependencies.logger;
60
+ this.httpService = dependencies.httpService;
61
+ this.redis = dependencies.redis;
62
+ if (config) {
63
+ this.initializeFromConfig(config);
64
+ }
65
+ }
66
+ /**
67
+ * 从配置初始化
68
+ */
69
+ initializeFromConfig(config) {
70
+ const { defaultVendor, providers } = config;
71
+ const providerConfig = providers.find((p) => p.vendor === defaultVendor);
72
+ if (!providerConfig) {
73
+ this.logger.warn(`SMS provider not found: ${defaultVendor}`);
74
+ return;
75
+ }
76
+ // 使用类型断言来绕过 readonly 限制(仅在构造函数中)
77
+ this.provider = providerConfig;
78
+ this.vendor = defaultVendor;
79
+ this.client = this.createClient(providerConfig);
80
+ // 初始化模板
81
+ this.initializeTemplates(providerConfig);
82
+ }
83
+ /**
84
+ * 初始化模板配置
85
+ */
86
+ initializeTemplates(provider) {
87
+ if (!provider.templates)
88
+ return;
89
+ provider.templates.forEach((template) => {
90
+ const meta = template;
91
+ const name = meta.name || 'default';
92
+ this.templates[name] = template;
93
+ });
94
+ if (environment_util_1.default.isProduction()) {
95
+ this.logger.info(`SMS templates initialized: ${Object.keys(this.templates).join(', ')}`);
96
+ }
97
+ }
98
+ /**
99
+ * 创建 SMS 客户端
100
+ */
101
+ createClient(provider) {
102
+ const vendor = provider.vendor;
103
+ if (environment_util_1.default.isProduction()) {
104
+ this.logger.info(`Creating SMS client for vendor: ${types_1.SMS_VENDOR_NAMES[vendor] || vendor}`);
105
+ }
106
+ switch (vendor) {
107
+ case 'aliyun':
108
+ return new infra_clients_1.SmsAliyunClient(provider, this.logger);
109
+ case 'tencent':
110
+ return new infra_clients_1.SmsTencentClient(provider, this.logger);
111
+ case 'http':
112
+ if (!this.httpService) {
113
+ throw new Error('HttpService is required for HTTP SMS client');
114
+ }
115
+ return new infra_clients_1.SmsHttpClient(provider, this.httpService, this.logger);
116
+ case 'zxjcsms':
117
+ if (!this.httpService) {
118
+ throw new Error('HttpService is required for ZXJC SMS client');
119
+ }
120
+ return new infra_clients_1.SmsZxjcClient(provider, this.httpService, this.logger);
121
+ case 'volcengine':
122
+ if (!this.redis) {
123
+ throw new Error('RedisService is required for Volcengine SMS client');
124
+ }
125
+ return new infra_clients_1.SmsVolcengineClient(provider, this.redis, this.logger);
126
+ default:
127
+ throw new Error(`Unsupported SMS vendor: ${vendor}`);
128
+ }
129
+ }
130
+ // ========================================================================
131
+ // Public Accessors
132
+ // ========================================================================
133
+ /**
134
+ * 检查工厂是否已初始化
135
+ */
136
+ get isInitialized() {
137
+ return this.client !== null;
138
+ }
139
+ /**
140
+ * 获取当前供应商类型
141
+ */
142
+ get currentVendor() {
143
+ return this.vendor;
144
+ }
145
+ /**
146
+ * 获取当前供应商显示名称
147
+ */
148
+ get currentVendorName() {
149
+ return this.vendor ? types_1.SMS_VENDOR_NAMES[this.vendor] : 'Unknown';
150
+ }
151
+ /**
152
+ * 检查是否为火山引擎供应商
153
+ */
154
+ get isVolcengine() {
155
+ return this.vendor === 'volcengine';
156
+ }
157
+ /**
158
+ * 获取所有模板名称
159
+ */
160
+ get templateNames() {
161
+ return Object.keys(this.templates);
162
+ }
163
+ // ========================================================================
164
+ // Template Management
165
+ // ========================================================================
166
+ /**
167
+ * 获取模板配置
168
+ *
169
+ * @param templateId - 模板 ID
170
+ * @returns 模板配置,不存在返回 undefined
171
+ */
172
+ getTemplate(templateId) {
173
+ return this.templates[templateId];
174
+ }
175
+ /**
176
+ * 获取模板配置(必须存在)
177
+ *
178
+ * @param templateId - 模板 ID
179
+ * @throws Error 如果模板不存在
180
+ */
181
+ getTemplateOrThrow(templateId) {
182
+ const template = this.templates[templateId];
183
+ if (!template) {
184
+ throw new Error(`SMS template not found: ${templateId}`);
185
+ }
186
+ return template;
187
+ }
188
+ /**
189
+ * 获取模板元数据
190
+ *
191
+ * @param templateId - 模板 ID
192
+ * @returns 模板元数据
193
+ */
194
+ getTemplateMeta(templateId) {
195
+ const template = this.templates[templateId];
196
+ if (!template)
197
+ return undefined;
198
+ return {
199
+ name: template.name,
200
+ frequency: template.frequency,
201
+ codeExpire: template.codeExpire,
202
+ };
203
+ }
204
+ // ========================================================================
205
+ // SMS Operations
206
+ // ========================================================================
207
+ /**
208
+ * 发送短信验证码
209
+ *
210
+ * @param phone - 手机号码
211
+ * @param code - 验证码
212
+ * @param templateId - 模板 ID
213
+ * @returns 发送结果
214
+ */
215
+ async sendSmsCode(phone, code, templateId = 'verify') {
216
+ this.ensureInitialized();
217
+ const template = this.getTemplateOrThrow(templateId);
218
+ this.logger.info(`Sending SMS code to ${phone}`, {
219
+ vendor: this.currentVendorName,
220
+ templateId,
221
+ });
222
+ return await this.client.sendSmsCode(phone, code, template);
223
+ }
224
+ /**
225
+ * 发送验证码(火山引擎自动生成)
226
+ *
227
+ * 仅火山引擎供应商支持此功能
228
+ *
229
+ * @param phoneNumber - 手机号码
230
+ * @param templateId - 模板 ID
231
+ * @throws Error 如果当前供应商不是火山引擎
232
+ */
233
+ async sendVerifyCode(phoneNumber, templateId = 'verify') {
234
+ this.ensureInitialized();
235
+ this.ensureVolcengine('sendVerifyCode');
236
+ const template = this.getTemplateOrThrow(templateId);
237
+ return await this.client.sendVerifyCode(phoneNumber, template);
238
+ }
239
+ /**
240
+ * 校验验证码(火山引擎)
241
+ *
242
+ * 仅火山引擎供应商支持此功能
243
+ *
244
+ * @param phoneNumber - 手机号码
245
+ * @param code - 验证码
246
+ * @param templateId - 模板 ID
247
+ * @throws Error 如果当前供应商不是火山引擎
248
+ */
249
+ async checkVerifyCode(phoneNumber, code, templateId = 'verify') {
250
+ this.ensureInitialized();
251
+ this.ensureVolcengine('checkVerifyCode');
252
+ const template = this.getTemplateOrThrow(templateId);
253
+ return await this.client.checkVerifyCode(phoneNumber, code, template);
254
+ }
255
+ // ========================================================================
256
+ // Private Helpers
257
+ // ========================================================================
258
+ /**
259
+ * 确保工厂已初始化
260
+ */
261
+ ensureInitialized() {
262
+ if (!this.client) {
263
+ throw new Error('SMS client not initialized. Check SMS configuration.');
264
+ }
265
+ }
266
+ /**
267
+ * 确保当前供应商为火山引擎
268
+ */
269
+ ensureVolcengine(methodName) {
270
+ if (!this.isVolcengine) {
271
+ throw new Error(`${methodName} is only supported by Volcengine SMS`);
272
+ }
273
+ }
274
+ }
275
+ exports.SmsClientFactory = SmsClientFactory;
276
+ //# sourceMappingURL=sms.factory.js.map