diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
index 60c1d71a..af8aac99 100644
--- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
@@ -587,6 +587,7 @@ export default {
commFeature: "Commercial feature",
smsProvider: "SMS provider",
aliyunSms: "Aliyun SMS",
+ tencentSms: "Tencent SMS",
yfySms: "YFY SMS",
smsTest: "SMS test",
testMobilePlaceholder: "Enter test mobile number",
diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
index 60ea53a5..ed5b7207 100644
--- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
@@ -593,6 +593,7 @@ export default {
commFeature: "商业版功能",
smsProvider: "短信提供商",
aliyunSms: "阿里云短信",
+ tencentSms: "腾讯云短信",
yfySms: "易发云短信",
smsTest: "短信测试",
testMobilePlaceholder: "输入测试手机号",
diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue
index 2272ae8f..d115f1f9 100644
--- a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue
+++ b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue
@@ -45,6 +45,7 @@
{{ t("certd.aliyunSms") }}
+ {{ t("certd.tencentSms") }}
{{ t("certd.yfySms") }}
diff --git a/packages/ui/certd-server/src/controller/sys/settings/sys-settings-controller.ts b/packages/ui/certd-server/src/controller/sys/settings/sys-settings-controller.ts
index 14f58f5b..ac9bb252 100644
--- a/packages/ui/certd-server/src/controller/sys/settings/sys-settings-controller.ts
+++ b/packages/ui/certd-server/src/controller/sys/settings/sys-settings-controller.ts
@@ -164,7 +164,8 @@ export class SysSettingsController extends CrudController {
@Post('/getSmsTypeDefine', { summary: 'sys:settings:view' })
async getSmsTypeDefine(@Body('type') type: string) {
- return this.ok(SmsServiceFactory.getDefine(type));
+ const define =await SmsServiceFactory.getDefine(type);
+ return this.ok(define);
}
diff --git a/packages/ui/certd-server/src/modules/basic/service/code-service.ts b/packages/ui/certd-server/src/modules/basic/service/code-service.ts
index 93445b7d..1a252efc 100644
--- a/packages/ui/certd-server/src/modules/basic/service/code-service.ts
+++ b/packages/ui/certd-server/src/modules/basic/service/code-service.ts
@@ -83,7 +83,7 @@ export class CodeService {
}
const smsType = sysSettings.sms.type;
const smsConfig = sysSettings.sms.config;
- const sender: ISmsService = SmsServiceFactory.createSmsService(smsType);
+ const sender: ISmsService = await SmsServiceFactory.createSmsService(smsType);
const accessGetter = new AccessSysGetter(this.accessService);
sender.setCtx({
accessService: accessGetter,
diff --git a/packages/ui/certd-server/src/modules/basic/sms/factory.ts b/packages/ui/certd-server/src/modules/basic/sms/factory.ts
index 48a33886..74566e54 100644
--- a/packages/ui/certd-server/src/modules/basic/sms/factory.ts
+++ b/packages/ui/certd-server/src/modules/basic/sms/factory.ts
@@ -1,25 +1,28 @@
-import { AliyunSmsService } from './aliyun-sms.js';
-import { YfySmsService } from './yfy-sms.js';
export class SmsServiceFactory {
- static createSmsService(type: string) {
- const cls = this.GetClassByType(type);
+ static async createSmsService(type: string) {
+ const cls = await this.GetClassByType(type);
return new cls();
}
- static GetClassByType(type: string) {
+ static async GetClassByType(type: string) {
switch (type) {
case 'aliyun':
+ const {AliyunSmsService} = await import("./aliyun-sms.js")
return AliyunSmsService;
case 'yfysms':
+ const {YfySmsService} = await import("./yfy-sms.js")
return YfySmsService;
+ case 'tencent':
+ const {TencentSmsService} = await import("./tencent-sms.js")
+ return TencentSmsService;
default:
throw new Error('不支持的短信服务类型');
}
}
- static getDefine(type: string) {
- const cls = this.GetClassByType(type);
+ static async getDefine(type: string) {
+ const cls = await this.GetClassByType(type);
return cls.getDefine();
}
}
diff --git a/packages/ui/certd-server/src/modules/basic/sms/tencent-sms.ts b/packages/ui/certd-server/src/modules/basic/sms/tencent-sms.ts
new file mode 100644
index 00000000..4032aff4
--- /dev/null
+++ b/packages/ui/certd-server/src/modules/basic/sms/tencent-sms.ts
@@ -0,0 +1,124 @@
+import {ISmsService, PluginInputs, SmsPluginCtx} from './api.js';
+import {TencentAccess} from "@certd/plugin-lib";
+
+export type TencentSmsConfig = {
+ accessId: string;
+ signName: string;
+ codeTemplateId: string;
+ appId: string;
+ region: string;
+};
+
+export class TencentSmsService implements ISmsService {
+ static getDefine() {
+ return {
+ name: 'tencent',
+ desc: '腾讯云短信服务',
+ input: {
+ accessId: {
+ title: '腾讯云授权',
+ component: {
+ name: 'access-selector',
+ type: 'tencent',
+ },
+ required: true,
+ },
+ region: {
+ title: '区域',
+ value:"ap-beijing",
+ component: {
+ name: 'a-select',
+ vModel: 'value',
+ options:[
+ {value:"ap-beijing",label:"华北地区(北京)"},
+ {value:"ap-guangzhou",label:"华南地区(广州)"},
+ {value:"ap-nanjing",label:"华东地区(南京)"},
+ ]
+ },
+ helper:"随便选一个",
+ required: true,
+ },
+ signName: {
+ title: '签名',
+ component: {
+ name: 'a-input',
+ vModel: 'value',
+ },
+ required: true,
+ },
+ appId: {
+ title: '应用ID',
+ component: {
+ name: 'a-input',
+ vModel: 'value',
+ },
+ required: true,
+ },
+ codeTemplateId: {
+ title: '验证码模板Id',
+ component: {
+ name: 'a-input',
+ vModel: 'value',
+ },
+ required: true,
+ },
+ } as PluginInputs,
+ };
+ }
+
+ ctx: SmsPluginCtx;
+
+ setCtx(ctx: any) {
+ this.ctx = ctx;
+ }
+
+
+ async getClient() {
+ const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/sms/v20210111/index.js');
+ const client = sdk.v20210111.Client;
+ const access = await this.ctx.accessService.getById(this.ctx.config.accessId);
+
+
+ // const region = this.region;
+ const clientConfig = {
+ credential: {
+ secretId: access.secretId,
+ secretKey: access.secretKey,
+ },
+ region: this.ctx.config.region,
+ profile: {
+ httpProfile: {
+ endpoint: `sms.${access.intlDomain()}tencentcloudapi.com`,
+ },
+ },
+ };
+
+ return new client(clientConfig);
+ }
+
+ async sendSmsCode(opts: { mobile: string; code: string; phoneCode: string }) {
+ const { mobile, code, phoneCode } = opts;
+
+ const client = await this.getClient();
+ const smsConfig = this.ctx.config;
+ const params = {
+ "PhoneNumberSet": [
+ `+${phoneCode}${mobile}`
+ ],
+ "SmsSdkAppId": smsConfig.appId,
+ "TemplateId": smsConfig.codeTemplateId,
+ "SignName": smsConfig.signName,
+ "TemplateParamSet": [
+ code
+ ]
+ };
+ const ret = await client.SendSms(params);
+ this.checkRet(ret);
+ }
+
+ checkRet(ret: any) {
+ if (!ret || ret.Error) {
+ throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);
+ }
+ }
+}