'use strict'; const Service = require('egg').Service; /** * 短信网关服务(阿里云 Dysmsapi) * * 仅负责把"服务端已生成的验证码"下发给手机号,不参与验证码的存证与校验 * (校验仍由 ctx.session 在 auth 控制器中完成,契约见 verify_sms_and_import_lock 测试)。 * * 依赖 SDK(生产环境需 npm install): * @alicloud/openapi-client * @alicloud/dysmsapi20170525 * @alicloud/tea-util */ class SmsService extends Service { /** * 发送短信验证码 * @param {string} phone - 接收短信的手机号 * @param {string} code - 6 位验证码(由调用方生成并存入 session) * @returns {Promise<{ok:boolean, message:string}>} */ async sendVerifyCode(phone, code) { const { ctx, app } = this; const cfg = app.config.sms && app.config.sms.aliyun; if (!cfg || !cfg.accessKeyId || !cfg.accessKeySecret) { ctx.logger.error('[短信网关] 未配置阿里云密钥,无法发送'); return { ok: false, message: '短信网关未配置' }; } let OpenApi; let Dysmsapi; let Util; try { OpenApi = require('@alicloud/openapi-client'); Dysmsapi = require('@alicloud/dysmsapi20170525'); Util = require('@alicloud/tea-util'); } catch (e) { ctx.logger.error('[短信网关] 未安装阿里云 SDK:' + e.message); return { ok: false, message: '短信网关 SDK 未安装' }; } try { const config = new OpenApi.Config({ accessKeyId: cfg.accessKeyId, accessKeySecret: cfg.accessKeySecret, endpoint: cfg.endpoint, }); const client = new Dysmsapi.default(config); const request = new Dysmsapi.SendSmsRequest({ phoneNumbers: String(phone), signName: cfg.signName, templateCode: cfg.templateCode, templateParam: JSON.stringify({ code: String(code) }), }); const runtime = new Util.RuntimeOptions({}); runtime.readTimeout = 5000; runtime.connectTimeout = 5000; const response = await client.sendSmsWithOptions(request, runtime); const body = response && response.body; if (body && body.code === 'OK') { ctx.logger.info(`[短信网关] 验证码已下发至 ${phone}`); return { ok: true, message: '验证码发送成功' }; } const reason = (body && (body.message || body.code)) || '未知错误'; ctx.logger.error(`[短信网关] 下发失败:${reason}`); return { ok: false, message: reason }; } catch (err) { ctx.logger.error('[短信网关] 调用异常:' + (err && err.message)); return { ok: false, message: (err && err.message) || '短信网关调用异常' }; } } } module.exports = SmsService;