@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.
- package/dist/email/dto/email.dto.d.ts +70 -0
- package/dist/email/dto/email.dto.d.ts.map +1 -0
- package/dist/email/dto/email.dto.js +58 -0
- package/dist/email/dto/email.dto.js.map +1 -0
- package/dist/email/email.module.d.ts +3 -0
- package/dist/email/email.module.d.ts.map +1 -0
- package/dist/email/email.module.js +38 -0
- package/dist/email/email.module.js.map +1 -0
- package/dist/email/email.service.d.ts +61 -0
- package/dist/email/email.service.d.ts.map +1 -0
- package/dist/email/email.service.js +191 -0
- package/dist/email/email.service.js.map +1 -0
- package/dist/email/index.d.ts +5 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +26 -0
- package/dist/email/index.js.map +1 -0
- package/dist/file-storage/bucket-resolver.d.ts +174 -0
- package/dist/file-storage/bucket-resolver.d.ts.map +1 -0
- package/dist/file-storage/bucket-resolver.js +270 -0
- package/dist/file-storage/bucket-resolver.js.map +1 -0
- package/dist/file-storage/file-storage.factory.d.ts +183 -0
- package/dist/file-storage/file-storage.factory.d.ts.map +1 -0
- package/dist/file-storage/file-storage.factory.js +300 -0
- package/dist/file-storage/file-storage.factory.js.map +1 -0
- package/dist/file-storage/file-storage.module.d.ts +49 -0
- package/dist/file-storage/file-storage.module.d.ts.map +1 -0
- package/dist/file-storage/file-storage.module.js +74 -0
- package/dist/file-storage/file-storage.module.js.map +1 -0
- package/dist/file-storage/file-storage.service.d.ts +381 -0
- package/dist/file-storage/file-storage.service.d.ts.map +1 -0
- package/dist/file-storage/file-storage.service.js +598 -0
- package/dist/file-storage/file-storage.service.js.map +1 -0
- package/dist/file-storage/index.d.ts +43 -0
- package/dist/file-storage/index.d.ts.map +1 -0
- package/dist/file-storage/index.js +65 -0
- package/dist/file-storage/index.js.map +1 -0
- package/dist/file-storage/types.d.ts +187 -0
- package/dist/file-storage/types.d.ts.map +1 -0
- package/dist/file-storage/types.js +21 -0
- package/dist/file-storage/types.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/ip-geo/continent-mapping.d.ts +31 -0
- package/dist/ip-geo/continent-mapping.d.ts.map +1 -0
- package/dist/ip-geo/continent-mapping.js +246 -0
- package/dist/ip-geo/continent-mapping.js.map +1 -0
- package/dist/ip-geo/index.d.ts +33 -0
- package/dist/ip-geo/index.d.ts.map +1 -0
- package/dist/ip-geo/index.js +41 -0
- package/dist/ip-geo/index.js.map +1 -0
- package/dist/ip-geo/ip-geo.module.d.ts +8 -0
- package/dist/ip-geo/ip-geo.module.d.ts.map +1 -0
- package/dist/ip-geo/ip-geo.module.js +34 -0
- package/dist/ip-geo/ip-geo.module.js.map +1 -0
- package/dist/ip-geo/ip-geo.service.d.ts +43 -0
- package/dist/ip-geo/ip-geo.service.d.ts.map +1 -0
- package/dist/ip-geo/ip-geo.service.js +153 -0
- package/dist/ip-geo/ip-geo.service.js.map +1 -0
- package/dist/ip-info/index.d.ts +7 -0
- package/dist/ip-info/index.d.ts.map +1 -0
- package/dist/ip-info/index.js +13 -0
- package/dist/ip-info/index.js.map +1 -0
- package/dist/ip-info/ip-info.client.d.ts +32 -0
- package/dist/ip-info/ip-info.client.d.ts.map +1 -0
- package/dist/ip-info/ip-info.client.js +73 -0
- package/dist/ip-info/ip-info.client.js.map +1 -0
- package/dist/ip-info/ip-info.module.d.ts +3 -0
- package/dist/ip-info/ip-info.module.d.ts.map +1 -0
- package/dist/ip-info/ip-info.module.js +45 -0
- package/dist/ip-info/ip-info.module.js.map +1 -0
- package/dist/ip-info/ip-info.service.d.ts +50 -0
- package/dist/ip-info/ip-info.service.d.ts.map +1 -0
- package/dist/ip-info/ip-info.service.js +177 -0
- package/dist/ip-info/ip-info.service.js.map +1 -0
- package/dist/ocr/index.d.ts +33 -0
- package/dist/ocr/index.d.ts.map +1 -0
- package/dist/ocr/index.js +53 -0
- package/dist/ocr/index.js.map +1 -0
- package/dist/ocr/ocr.module.d.ts +41 -0
- package/dist/ocr/ocr.module.d.ts.map +1 -0
- package/dist/ocr/ocr.module.js +61 -0
- package/dist/ocr/ocr.module.js.map +1 -0
- package/dist/ocr/ocr.service.d.ts +111 -0
- package/dist/ocr/ocr.service.d.ts.map +1 -0
- package/dist/ocr/ocr.service.js +214 -0
- package/dist/ocr/ocr.service.js.map +1 -0
- package/dist/sms/index.d.ts +5 -0
- package/dist/sms/index.d.ts.map +1 -0
- package/dist/sms/index.js +29 -0
- package/dist/sms/index.js.map +1 -0
- package/dist/sms/sms.factory.d.ts +140 -0
- package/dist/sms/sms.factory.d.ts.map +1 -0
- package/dist/sms/sms.factory.js +276 -0
- package/dist/sms/sms.factory.js.map +1 -0
- package/dist/sms/sms.module.d.ts +3 -0
- package/dist/sms/sms.module.d.ts.map +1 -0
- package/dist/sms/sms.module.js +38 -0
- package/dist/sms/sms.module.js.map +1 -0
- package/dist/sms/sms.service.d.ts +139 -0
- package/dist/sms/sms.service.d.ts.map +1 -0
- package/dist/sms/sms.service.js +278 -0
- package/dist/sms/sms.service.js.map +1 -0
- package/dist/sms/types.d.ts +204 -0
- package/dist/sms/types.d.ts.map +1 -0
- package/dist/sms/types.js +44 -0
- package/dist/sms/types.js.map +1 -0
- package/dist/streaming-asr/index.d.ts +45 -0
- package/dist/streaming-asr/index.d.ts.map +1 -0
- package/dist/streaming-asr/index.js +66 -0
- package/dist/streaming-asr/index.js.map +1 -0
- package/dist/streaming-asr/streaming-asr.module.d.ts +37 -0
- package/dist/streaming-asr/streaming-asr.module.d.ts.map +1 -0
- package/dist/streaming-asr/streaming-asr.module.js +59 -0
- package/dist/streaming-asr/streaming-asr.module.js.map +1 -0
- package/dist/streaming-asr/streaming-asr.service.d.ts +276 -0
- package/dist/streaming-asr/streaming-asr.service.d.ts.map +1 -0
- package/dist/streaming-asr/streaming-asr.service.js +1120 -0
- package/dist/streaming-asr/streaming-asr.service.js.map +1 -0
- package/dist/streaming-asr/types.d.ts +194 -0
- package/dist/streaming-asr/types.d.ts.map +1 -0
- package/dist/streaming-asr/types.js +8 -0
- package/dist/streaming-asr/types.js.map +1 -0
- package/dist/system-health/index.d.ts +7 -0
- package/dist/system-health/index.d.ts.map +1 -0
- package/dist/system-health/index.js +25 -0
- package/dist/system-health/index.js.map +1 -0
- package/dist/system-health/system-health.controller.d.ts +43 -0
- package/dist/system-health/system-health.controller.d.ts.map +1 -0
- package/dist/system-health/system-health.controller.js +86 -0
- package/dist/system-health/system-health.controller.js.map +1 -0
- package/dist/system-health/system-health.module.d.ts +3 -0
- package/dist/system-health/system-health.module.d.ts.map +1 -0
- package/dist/system-health/system-health.module.js +29 -0
- package/dist/system-health/system-health.module.js.map +1 -0
- package/dist/system-health/system-health.service.d.ts +14 -0
- package/dist/system-health/system-health.service.d.ts.map +1 -0
- package/dist/system-health/system-health.service.js +87 -0
- package/dist/system-health/system-health.service.js.map +1 -0
- package/dist/uploader/index.d.ts +3 -0
- package/dist/uploader/index.d.ts.map +1 -0
- package/dist/uploader/index.js +8 -0
- package/dist/uploader/index.js.map +1 -0
- package/dist/uploader/uploader.module.d.ts +3 -0
- package/dist/uploader/uploader.module.d.ts.map +1 -0
- package/dist/uploader/uploader.module.js +25 -0
- package/dist/uploader/uploader.module.js.map +1 -0
- package/dist/uploader/uploader.service.d.ts +86 -0
- package/dist/uploader/uploader.service.d.ts.map +1 -0
- package/dist/uploader/uploader.service.js +188 -0
- package/dist/uploader/uploader.service.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COUNTRY_TO_CONTINENT = exports.CONTINENT_COUNTRIES = exports.getContinentByCountry = exports.IpGeoService = exports.IpGeoModule = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview IP 地理位置服务导出入口(Infra 层)
|
|
6
|
+
*
|
|
7
|
+
* 本模块提供纯 infra 层的 IP 地理位置服务:
|
|
8
|
+
* - IpGeoService: IP 地理位置查询服务
|
|
9
|
+
* - IpGeoModule: NestJS 模块
|
|
10
|
+
* - getContinentByCountry: 静态大洲映射函数
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { IpGeoModule, IpGeoService } from '@dofe/infra-shared-services';
|
|
15
|
+
*
|
|
16
|
+
* @Module({
|
|
17
|
+
* imports: [IpGeoModule],
|
|
18
|
+
* })
|
|
19
|
+
* export class MyModule {}
|
|
20
|
+
*
|
|
21
|
+
* @Injectable()
|
|
22
|
+
* class MyService {
|
|
23
|
+
* constructor(private readonly ipGeo: IpGeoService) {}
|
|
24
|
+
*
|
|
25
|
+
* async getRegion(ip: string) {
|
|
26
|
+
* return await this.ipGeo.getContinent(ip);
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @module ip-geo
|
|
32
|
+
*/
|
|
33
|
+
var ip_geo_module_1 = require("./ip-geo.module");
|
|
34
|
+
Object.defineProperty(exports, "IpGeoModule", { enumerable: true, get: function () { return ip_geo_module_1.IpGeoModule; } });
|
|
35
|
+
var ip_geo_service_1 = require("./ip-geo.service");
|
|
36
|
+
Object.defineProperty(exports, "IpGeoService", { enumerable: true, get: function () { return ip_geo_service_1.IpGeoService; } });
|
|
37
|
+
var continent_mapping_1 = require("./continent-mapping");
|
|
38
|
+
Object.defineProperty(exports, "getContinentByCountry", { enumerable: true, get: function () { return continent_mapping_1.getContinentByCountry; } });
|
|
39
|
+
Object.defineProperty(exports, "CONTINENT_COUNTRIES", { enumerable: true, get: function () { return continent_mapping_1.CONTINENT_COUNTRIES; } });
|
|
40
|
+
Object.defineProperty(exports, "COUNTRY_TO_CONTINENT", { enumerable: true, get: function () { return continent_mapping_1.COUNTRY_TO_CONTINENT; } });
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ip-geo/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,iDAA8C;AAArC,4GAAA,WAAW,OAAA;AACpB,mDAAgD;AAAvC,8GAAA,YAAY,OAAA;AACrB,yDAK6B;AAJ3B,0HAAA,qBAAqB,OAAA;AAErB,wHAAA,mBAAmB,OAAA;AACnB,yHAAA,oBAAoB,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-geo.module.d.ts","sourceRoot":"","sources":["../../src/ip-geo/ip-geo.module.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,qBAKa,WAAW;CAAG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IpGeoModule = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* @fileoverview IP 地理位置服务模块(Infra 层)
|
|
12
|
+
*
|
|
13
|
+
* @module ip-geo/module
|
|
14
|
+
*/
|
|
15
|
+
const common_1 = require("@nestjs/common");
|
|
16
|
+
const infra_redis_1 = require("@dofe/infra-redis");
|
|
17
|
+
const infra_clients_1 = require("@dofe/infra-clients");
|
|
18
|
+
const ip_geo_service_1 = require("./ip-geo.service");
|
|
19
|
+
/**
|
|
20
|
+
* IP 地理位置服务模块
|
|
21
|
+
*
|
|
22
|
+
* @description 提供纯 infra 层的 IP 地理位置服务,不依赖 domain 层。
|
|
23
|
+
*/
|
|
24
|
+
let IpGeoModule = class IpGeoModule {
|
|
25
|
+
};
|
|
26
|
+
exports.IpGeoModule = IpGeoModule;
|
|
27
|
+
exports.IpGeoModule = IpGeoModule = __decorate([
|
|
28
|
+
(0, common_1.Module)({
|
|
29
|
+
imports: [infra_redis_1.RedisModule, infra_clients_1.IpInfoClientModule],
|
|
30
|
+
providers: [ip_geo_service_1.IpGeoService],
|
|
31
|
+
exports: [ip_geo_service_1.IpGeoService],
|
|
32
|
+
})
|
|
33
|
+
], IpGeoModule);
|
|
34
|
+
//# sourceMappingURL=ip-geo.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-geo.module.js","sourceRoot":"","sources":["../../src/ip-geo/ip-geo.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA;;;;GAIG;AACH,2CAAwC;AACxC,mDAAgD;AAChD,uDAAyD;AACzD,qDAAgD;AAEhD;;;;GAIG;AAMI,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,kCAAW;sBAAX,WAAW;IALvB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,yBAAW,EAAE,kCAAkB,CAAC;QAC1C,SAAS,EAAE,CAAC,6BAAY,CAAC;QACzB,OAAO,EAAE,CAAC,6BAAY,CAAC;KACxB,CAAC;GACW,WAAW,CAAG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Logger } from 'winston';
|
|
2
|
+
import { RedisService } from '@dofe/infra-redis';
|
|
3
|
+
import { MinimalIpRequest } from '@dofe/infra-utils/ip.util';
|
|
4
|
+
import { PardxApp } from '@dofe/infra-common';
|
|
5
|
+
import { Continent } from './continent-mapping';
|
|
6
|
+
import { IpInfoClient } from '@dofe/infra-clients';
|
|
7
|
+
/**
|
|
8
|
+
* IP 地理位置服务(Infra 层)
|
|
9
|
+
*
|
|
10
|
+
* @description 提供 IP 地理位置查询功能,使用静态大洲映射,不依赖数据库。
|
|
11
|
+
*
|
|
12
|
+
* @class IpGeoService
|
|
13
|
+
*/
|
|
14
|
+
export declare class IpGeoService {
|
|
15
|
+
private readonly redis;
|
|
16
|
+
private readonly ipInfoClient;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
protected ipinfoRedisKey: string;
|
|
19
|
+
constructor(redis: RedisService, ipInfoClient: IpInfoClient, logger: Logger);
|
|
20
|
+
/**
|
|
21
|
+
* 从请求中提取 IP 地址
|
|
22
|
+
*/
|
|
23
|
+
extractIp(req: MinimalIpRequest): string;
|
|
24
|
+
/**
|
|
25
|
+
* 获取 IP 信息
|
|
26
|
+
*/
|
|
27
|
+
getIpInfo(ip: string): Promise<Partial<PardxApp.IPInfo>>;
|
|
28
|
+
/**
|
|
29
|
+
* 获取 IP 对应的国家代码
|
|
30
|
+
*/
|
|
31
|
+
getIpCountry(ip: string): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取 IP 对应的大洲
|
|
34
|
+
*
|
|
35
|
+
* @description 使用静态映射,不依赖数据库
|
|
36
|
+
*/
|
|
37
|
+
getContinent(ip: string): Promise<Continent>;
|
|
38
|
+
/**
|
|
39
|
+
* 获取 IP 对应的时区
|
|
40
|
+
*/
|
|
41
|
+
getTimeZone(ip: string): Promise<string>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ip-geo.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-geo.service.d.ts","sourceRoot":"","sources":["../../src/ip-geo/ip-geo.service.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAyB,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAkB,MAAM,qBAAqB,CAAC;AAEnE;;;;;;GAMG;AACH,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IACI,OAAO,CAAC,QAAQ,CAAC,MAAM;IAL1D,SAAS,CAAC,cAAc,SAAY;gBAGjB,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,YAAY,EACO,MAAM,EAAE,MAAM;IAGlE;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM;IAIxC;;OAEG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAwD9D;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/C;;;;OAIG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAMlD;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAI/C"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.IpGeoService = void 0;
|
|
19
|
+
/**
|
|
20
|
+
* @fileoverview IP 地理位置服务(Infra 层)
|
|
21
|
+
*
|
|
22
|
+
* 本服务提供纯 infra 层的 IP 地理位置查询功能:
|
|
23
|
+
* - IP 信息查询(via IpInfoClient)
|
|
24
|
+
* - 国家代码查询
|
|
25
|
+
* - 大洲查询(使用静态映射,不依赖数据库)
|
|
26
|
+
*
|
|
27
|
+
* 注意:此服务不依赖 domain 层,可在 infra 层安全使用。
|
|
28
|
+
* 如需完整的 IP 信息服务(含数据库查询),请使用 domain/services/ip-info。
|
|
29
|
+
*
|
|
30
|
+
* @module ip-geo/service
|
|
31
|
+
*/
|
|
32
|
+
const common_1 = require("@nestjs/common");
|
|
33
|
+
const nest_winston_1 = require("nest-winston");
|
|
34
|
+
const winston_1 = require("winston");
|
|
35
|
+
const infra_redis_1 = require("@dofe/infra-redis");
|
|
36
|
+
const ip_util_1 = __importDefault(require("@dofe/infra-utils/ip.util"));
|
|
37
|
+
const validate_util_1 = __importDefault(require("@dofe/infra-utils/validate.util"));
|
|
38
|
+
const environment_util_1 = __importDefault(require("@dofe/infra-utils/environment.util"));
|
|
39
|
+
const continent_mapping_1 = require("./continent-mapping");
|
|
40
|
+
const infra_clients_1 = require("@dofe/infra-clients");
|
|
41
|
+
/**
|
|
42
|
+
* IP 地理位置服务(Infra 层)
|
|
43
|
+
*
|
|
44
|
+
* @description 提供 IP 地理位置查询功能,使用静态大洲映射,不依赖数据库。
|
|
45
|
+
*
|
|
46
|
+
* @class IpGeoService
|
|
47
|
+
*/
|
|
48
|
+
let IpGeoService = class IpGeoService {
|
|
49
|
+
redis;
|
|
50
|
+
ipInfoClient;
|
|
51
|
+
logger;
|
|
52
|
+
ipinfoRedisKey = 'ipinfo';
|
|
53
|
+
constructor(redis, ipInfoClient, logger) {
|
|
54
|
+
this.redis = redis;
|
|
55
|
+
this.ipInfoClient = ipInfoClient;
|
|
56
|
+
this.logger = logger;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 从请求中提取 IP 地址
|
|
60
|
+
*/
|
|
61
|
+
extractIp(req) {
|
|
62
|
+
return ip_util_1.default.extractIp(req);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 获取 IP 信息
|
|
66
|
+
*/
|
|
67
|
+
async getIpInfo(ip) {
|
|
68
|
+
if (environment_util_1.default.getBaseZone() === 'cn') {
|
|
69
|
+
return {
|
|
70
|
+
ip,
|
|
71
|
+
country: 'CN',
|
|
72
|
+
region: 'Beijing',
|
|
73
|
+
city: 'Beijing',
|
|
74
|
+
loc: '1.2897,103.8501',
|
|
75
|
+
timezone: 'Asia/Shanghai',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (validate_util_1.default.isBlank(ip) || ip === '127.0.0.1') {
|
|
79
|
+
return {
|
|
80
|
+
ip,
|
|
81
|
+
country: 'SG',
|
|
82
|
+
region: 'Singapore',
|
|
83
|
+
city: 'Singapore',
|
|
84
|
+
loc: '1.2897,103.8501',
|
|
85
|
+
timezone: 'Asia/Singapore',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const ipinfo = await this.redis.getData(this.ipinfoRedisKey, ip);
|
|
89
|
+
if (ipinfo)
|
|
90
|
+
return ipinfo;
|
|
91
|
+
try {
|
|
92
|
+
const response = await this.ipInfoClient.getIpInfo(ip);
|
|
93
|
+
let ipInfoData = response;
|
|
94
|
+
this.logger.info('IP info:', { ipInfoData });
|
|
95
|
+
await this.redis.saveData(this.ipinfoRedisKey, ip, ipInfoData);
|
|
96
|
+
if (ipInfoData.country === 'CN') {
|
|
97
|
+
ipInfoData = {
|
|
98
|
+
ip,
|
|
99
|
+
country: 'SG',
|
|
100
|
+
region: 'Singapore',
|
|
101
|
+
city: 'Singapore',
|
|
102
|
+
loc: '1.2897,103.8501',
|
|
103
|
+
timezone: 'Asia/Singapore',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return ipInfoData;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
this.logger.error('Failed to fetch IP info:', error);
|
|
110
|
+
return {
|
|
111
|
+
ip,
|
|
112
|
+
country: 'SG',
|
|
113
|
+
region: 'Singapore',
|
|
114
|
+
city: 'Singapore',
|
|
115
|
+
loc: '1.2897,103.8501',
|
|
116
|
+
timezone: 'Asia/Singapore',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 获取 IP 对应的国家代码
|
|
122
|
+
*/
|
|
123
|
+
async getIpCountry(ip) {
|
|
124
|
+
const ipInfo = await this.getIpInfo(ip);
|
|
125
|
+
return ipInfo.country ?? '';
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 获取 IP 对应的大洲
|
|
129
|
+
*
|
|
130
|
+
* @description 使用静态映射,不依赖数据库
|
|
131
|
+
*/
|
|
132
|
+
async getContinent(ip) {
|
|
133
|
+
const countryCode = await this.getIpCountry(ip);
|
|
134
|
+
const defaultZone = environment_util_1.default.getBaseZone();
|
|
135
|
+
return (0, continent_mapping_1.getContinentByCountry)(countryCode, defaultZone);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 获取 IP 对应的时区
|
|
139
|
+
*/
|
|
140
|
+
async getTimeZone(ip) {
|
|
141
|
+
const ipInfo = await this.getIpInfo(ip);
|
|
142
|
+
return ipInfo.timezone ?? '';
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
exports.IpGeoService = IpGeoService;
|
|
146
|
+
exports.IpGeoService = IpGeoService = __decorate([
|
|
147
|
+
(0, common_1.Injectable)(),
|
|
148
|
+
__param(2, (0, common_1.Inject)(nest_winston_1.WINSTON_MODULE_PROVIDER)),
|
|
149
|
+
__metadata("design:paramtypes", [infra_redis_1.RedisService,
|
|
150
|
+
infra_clients_1.IpInfoClient,
|
|
151
|
+
winston_1.Logger])
|
|
152
|
+
], IpGeoService);
|
|
153
|
+
//# sourceMappingURL=ip-geo.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-geo.service.js","sourceRoot":"","sources":["../../src/ip-geo/ip-geo.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ip-info/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IpInfoModule = exports.IpInfoClient = exports.IpInfoService = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* IP Info Service - Public API
|
|
6
|
+
*/
|
|
7
|
+
var ip_info_service_1 = require("./ip-info.service");
|
|
8
|
+
Object.defineProperty(exports, "IpInfoService", { enumerable: true, get: function () { return ip_info_service_1.IpInfoService; } });
|
|
9
|
+
var ip_info_client_1 = require("./ip-info.client");
|
|
10
|
+
Object.defineProperty(exports, "IpInfoClient", { enumerable: true, get: function () { return ip_info_client_1.IpInfoClient; } });
|
|
11
|
+
var ip_info_module_1 = require("./ip-info.module");
|
|
12
|
+
Object.defineProperty(exports, "IpInfoModule", { enumerable: true, get: function () { return ip_info_module_1.IpInfoModule; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ip-info/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,mDAAwE;AAA/D,8GAAA,YAAY,OAAA;AACrB,mDAAgD;AAAvC,8GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { HttpService } from '@nestjs/axios';
|
|
2
|
+
import { Logger } from 'winston';
|
|
3
|
+
/**
|
|
4
|
+
* ipinfo.io API 返回的原始数据结构
|
|
5
|
+
*/
|
|
6
|
+
export interface IpInfoApiResponse {
|
|
7
|
+
ip: string;
|
|
8
|
+
hostname?: string;
|
|
9
|
+
city?: string;
|
|
10
|
+
region?: string;
|
|
11
|
+
country: string;
|
|
12
|
+
loc: string;
|
|
13
|
+
org?: string;
|
|
14
|
+
postal?: string;
|
|
15
|
+
timezone: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class IpInfoClient {
|
|
18
|
+
private readonly httpService;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
private readonly API_TIMEOUT;
|
|
21
|
+
constructor(httpService: HttpService, logger: Logger);
|
|
22
|
+
/**
|
|
23
|
+
* 从 ipinfo.io 获取 IP 信息
|
|
24
|
+
*
|
|
25
|
+
* @param ip - IP 地址
|
|
26
|
+
* @param token - ipinfo.io API token
|
|
27
|
+
* @param baseUrl - API 基础 URL(默认:https://ipinfo.io)
|
|
28
|
+
* @returns IP 信息
|
|
29
|
+
*/
|
|
30
|
+
fetchIpInfo(ip: string, token: string, baseUrl?: string): Promise<IpInfoApiResponse>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=ip-info.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-info.client.d.ts","sourceRoot":"","sources":["../../src/ip-info/ip-info.client.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACK,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJ1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;gBAGjB,WAAW,EAAE,WAAW,EACS,MAAM,EAAE,MAAM;IAGlE;;;;;;;OAOG;IACG,WAAW,CACf,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC;CA0B9B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
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.IpInfoClient = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* IP Info Client
|
|
18
|
+
*
|
|
19
|
+
* 职责:封装 ipinfo.io API 的 HTTP 调用
|
|
20
|
+
* - 仅负责 HTTP 通信,不包含业务逻辑
|
|
21
|
+
* - 使用 @nestjs/axios 的 HttpService
|
|
22
|
+
*/
|
|
23
|
+
const common_1 = require("@nestjs/common");
|
|
24
|
+
const axios_1 = require("@nestjs/axios");
|
|
25
|
+
const nest_winston_1 = require("nest-winston");
|
|
26
|
+
const winston_1 = require("winston");
|
|
27
|
+
const rxjs_1 = require("rxjs");
|
|
28
|
+
let IpInfoClient = class IpInfoClient {
|
|
29
|
+
httpService;
|
|
30
|
+
logger;
|
|
31
|
+
API_TIMEOUT = 5000;
|
|
32
|
+
constructor(httpService, logger) {
|
|
33
|
+
this.httpService = httpService;
|
|
34
|
+
this.logger = logger;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 从 ipinfo.io 获取 IP 信息
|
|
38
|
+
*
|
|
39
|
+
* @param ip - IP 地址
|
|
40
|
+
* @param token - ipinfo.io API token
|
|
41
|
+
* @param baseUrl - API 基础 URL(默认:https://ipinfo.io)
|
|
42
|
+
* @returns IP 信息
|
|
43
|
+
*/
|
|
44
|
+
async fetchIpInfo(ip, token, baseUrl = 'https://ipinfo.io') {
|
|
45
|
+
const url = `${baseUrl}/${ip}?token=${token}`;
|
|
46
|
+
try {
|
|
47
|
+
this.logger.debug('[IpInfoClient] Fetching IP info', { ip, url });
|
|
48
|
+
const response = await (0, rxjs_1.firstValueFrom)(this.httpService.get(url, {
|
|
49
|
+
timeout: this.API_TIMEOUT,
|
|
50
|
+
}));
|
|
51
|
+
this.logger.debug('[IpInfoClient] IP info fetched successfully', {
|
|
52
|
+
ip,
|
|
53
|
+
data: response.data,
|
|
54
|
+
});
|
|
55
|
+
return response.data;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.logger.error('[IpInfoClient] Failed to fetch IP info', {
|
|
59
|
+
ip,
|
|
60
|
+
error: error.message || String(error),
|
|
61
|
+
});
|
|
62
|
+
throw new Error(`Failed to fetch IP info for ${ip}: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.IpInfoClient = IpInfoClient;
|
|
67
|
+
exports.IpInfoClient = IpInfoClient = __decorate([
|
|
68
|
+
(0, common_1.Injectable)(),
|
|
69
|
+
__param(1, (0, common_1.Inject)(nest_winston_1.WINSTON_MODULE_PROVIDER)),
|
|
70
|
+
__metadata("design:paramtypes", [axios_1.HttpService,
|
|
71
|
+
winston_1.Logger])
|
|
72
|
+
], IpInfoClient);
|
|
73
|
+
//# sourceMappingURL=ip-info.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-info.client.js","sourceRoot":"","sources":["../../src/ip-info/ip-info.client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;GAMG;AACH,2CAAoD;AACpD,yCAA4C;AAC5C,+CAAuD;AACvD,qCAAiC;AACjC,+BAAsC;AAkB/B,IAAM,YAAY,GAAlB,MAAM,YAAY;IAIJ;IACiC;IAJnC,WAAW,GAAG,IAAI,CAAC;IAEpC,YACmB,WAAwB,EACS,MAAc;QAD/C,gBAAW,GAAX,WAAW,CAAa;QACS,WAAM,GAAN,MAAM,CAAQ;IAC/D,CAAC;IAEJ;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CACf,EAAU,EACV,KAAa,EACb,UAAkB,mBAAmB;QAErC,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,EAAE,UAAU,KAAK,EAAE,CAAC;QAE9C,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAElE,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAc,EACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAoB,GAAG,EAAE;gBAC3C,OAAO,EAAE,IAAI,CAAC,WAAW;aAC1B,CAAC,CACH,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE;gBAC/D,EAAE;gBACF,IAAI,EAAE,QAAQ,CAAC,IAAI;aACpB,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE;gBAC1D,EAAE;gBACF,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;aACtC,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF,CAAA;AA9CY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAMR,WAAA,IAAA,eAAM,EAAC,sCAAuB,CAAC,CAAA;qCADF,mBAAW;QACiB,gBAAM;GALvD,YAAY,CA8CxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-info.module.d.ts","sourceRoot":"","sources":["../../src/ip-info/ip-info.module.ts"],"names":[],"mappings":"AAkBA,qBAaa,YAAY;CAAG"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IpInfoModule = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* IP Info Service Module
|
|
12
|
+
*
|
|
13
|
+
* 职责:提供 IP 信息查询服务
|
|
14
|
+
*
|
|
15
|
+
* 架构:
|
|
16
|
+
* - 位于 infra/shared-services(基础设施层)
|
|
17
|
+
* - 依赖 CountryCodeModule(domain 层)- 允许 infra 依赖 domain
|
|
18
|
+
* - 使用 HttpModule 进行外部 API 调用
|
|
19
|
+
*/
|
|
20
|
+
const common_1 = require("@nestjs/common");
|
|
21
|
+
const axios_1 = require("@nestjs/axios");
|
|
22
|
+
const config_1 = require("@nestjs/config");
|
|
23
|
+
const infra_redis_1 = require("@dofe/infra-redis");
|
|
24
|
+
const infra_shared_db_1 = require("@dofe/infra-shared-db");
|
|
25
|
+
const ip_info_client_1 = require("./ip-info.client");
|
|
26
|
+
const ip_info_service_1 = require("./ip-info.service");
|
|
27
|
+
let IpInfoModule = class IpInfoModule {
|
|
28
|
+
};
|
|
29
|
+
exports.IpInfoModule = IpInfoModule;
|
|
30
|
+
exports.IpInfoModule = IpInfoModule = __decorate([
|
|
31
|
+
(0, common_1.Module)({
|
|
32
|
+
imports: [
|
|
33
|
+
config_1.ConfigModule,
|
|
34
|
+
axios_1.HttpModule.register({
|
|
35
|
+
timeout: 5000,
|
|
36
|
+
maxRedirects: 5,
|
|
37
|
+
}),
|
|
38
|
+
infra_redis_1.RedisModule,
|
|
39
|
+
infra_shared_db_1.CountryCodeModule,
|
|
40
|
+
],
|
|
41
|
+
providers: [ip_info_client_1.IpInfoClient, ip_info_service_1.IpInfoService],
|
|
42
|
+
exports: [ip_info_service_1.IpInfoService],
|
|
43
|
+
})
|
|
44
|
+
], IpInfoModule);
|
|
45
|
+
//# sourceMappingURL=ip-info.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-info.module.js","sourceRoot":"","sources":["../../src/ip-info/ip-info.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA;;;;;;;;;GASG;AACH,2CAAwC;AACxC,yCAA2C;AAC3C,2CAA8C;AAC9C,mDAAgD;AAChD,2DAA0D;AAC1D,qDAAgD;AAChD,uDAAkD;AAe3C,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IAbxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,qBAAY;YACZ,kBAAU,CAAC,QAAQ,CAAC;gBAClB,OAAO,EAAE,IAAI;gBACb,YAAY,EAAE,CAAC;aAChB,CAAC;YACF,yBAAW;YACX,mCAAiB;SAClB;QACD,SAAS,EAAE,CAAC,6BAAY,EAAE,+BAAa,CAAC;QACxC,OAAO,EAAE,CAAC,+BAAa,CAAC;KACzB,CAAC;GACW,YAAY,CAAG"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Logger } from 'winston';
|
|
2
|
+
import { ConfigService } from '@nestjs/config';
|
|
3
|
+
import { RedisService } from '@dofe/infra-redis';
|
|
4
|
+
import { MinimalIpRequest } from '@dofe/infra-utils/ip.util';
|
|
5
|
+
import { PardxApp } from '@dofe/infra-common';
|
|
6
|
+
import { CountryCodeService } from '@dofe/infra-shared-db';
|
|
7
|
+
import { IpInfoClient } from './ip-info.client';
|
|
8
|
+
export declare class IpInfoService {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly redis;
|
|
11
|
+
private readonly countryCodeService;
|
|
12
|
+
private readonly ipInfoClient;
|
|
13
|
+
private readonly logger;
|
|
14
|
+
private ipInfoConfig;
|
|
15
|
+
protected ipinfoRedisKey: string;
|
|
16
|
+
constructor(config: ConfigService, redis: RedisService, countryCodeService: CountryCodeService, ipInfoClient: IpInfoClient, logger: Logger);
|
|
17
|
+
/**
|
|
18
|
+
* 从请求中提取 IP 地址
|
|
19
|
+
*/
|
|
20
|
+
extractIp(req: MinimalIpRequest): string;
|
|
21
|
+
/**
|
|
22
|
+
* 获取 IP 信息
|
|
23
|
+
*
|
|
24
|
+
* 业务逻辑:
|
|
25
|
+
* 1. CN 环境返回默认值
|
|
26
|
+
* 2. 本地 IP 返回默认值
|
|
27
|
+
* 3. 检查 Redis 缓存
|
|
28
|
+
* 4. 调用 ipinfo.io API(通过 IpInfoClient)
|
|
29
|
+
* 5. CN IP 替换为 SG(业务需求)
|
|
30
|
+
* 6. 失败时返回默认值
|
|
31
|
+
*/
|
|
32
|
+
getIpInfo(ip: string): Promise<Partial<PardxApp.IPInfo>>;
|
|
33
|
+
/**
|
|
34
|
+
* 获取 IP 所属国家
|
|
35
|
+
*/
|
|
36
|
+
getIpCountry(ip: string): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* 获取 IP 所属大洲
|
|
39
|
+
*/
|
|
40
|
+
getContinent(ip: string): Promise<string>;
|
|
41
|
+
/**
|
|
42
|
+
* 获取 IP 时区
|
|
43
|
+
*/
|
|
44
|
+
getTimeZone(ip: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* 生成默认 IP 信息
|
|
47
|
+
*/
|
|
48
|
+
private getDefaultIpInfo;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ip-info.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-info.service.d.ts","sourceRoot":"","sources":["../../src/ip-info/ip-info.service.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,qBACa,aAAa;IAKtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;IACI,OAAO,CAAC,QAAQ,CAAC,MAAM;IAR1D,OAAO,CAAC,YAAY,CAAe;IACnC,SAAS,CAAC,cAAc,SAAY;gBAGjB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,YAAY,EACnB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EACO,MAAM,EAAE,MAAM;IAKlE;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM;IAIxC;;;;;;;;;;OAUG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IA8D9D;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/C;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB/C;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9C;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAezB"}
|