96 lines
3.3 KiB
PHP
96 lines
3.3 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
declare (strict_types = 1);
|
|
|
|
namespace addon\smssend\subscribe;
|
|
|
|
use ywxapp\service\AddonService;
|
|
use ywxapp\utils\HttpClient;
|
|
use think\facade\Env;
|
|
use think\facade\Log;
|
|
|
|
/**
|
|
* 生产版短信发送订阅器
|
|
*
|
|
* 监听 ywxapp\library\Sms 触发的事件:
|
|
* - onSend($sms) -> SmsSend 验证码下发(返回 true/false 决定 Sms::send 是否成功落库)
|
|
* - onNotice($sms) -> SmsNotice 通知类短信(可选)
|
|
*
|
|
* 开发环境(app_debug=1)下不真正外发,避免无谓网络请求;生产环境调用配置的网关。
|
|
*
|
|
* 注意:ywxapp\service\AppService 默认已注册一个 SmsSend 监听——
|
|
* 开发环境返回 true(仅记录验证码);生产环境返回 null(交由本插件真正发送)。
|
|
* 因此生产环境务必启用本插件,否则 Sms::send 将因无监听器返回真值而失败。
|
|
*/
|
|
class Sender
|
|
{
|
|
protected $eventPrefix = 'Sms';
|
|
|
|
/**
|
|
* 下发验证码
|
|
* @param mixed $sms Sms 模型对象,可用 $sms['mobile']/$sms['code']/$sms['event'] 访问
|
|
* @return bool 发送是否成功(true 才会保留短信记录)
|
|
*/
|
|
public function onSend($sms): bool
|
|
{
|
|
$cfg = AddonService::config('smssend');
|
|
$api = $cfg['api_url'] ?? '';
|
|
if (!$api) {
|
|
Log::warning('[smssend] 未配置 api_url,无法发送短信');
|
|
return false;
|
|
}
|
|
|
|
// 开发环境不真正外发,避免无谓网络请求与密钥泄露
|
|
if (Env::get('app_debug')) {
|
|
Log::info('[smssend][DEV] 模拟发送 -> ' . ($sms['mobile'] ?? '') . ' code=' . ($sms['code'] ?? ''));
|
|
return true;
|
|
}
|
|
|
|
$sign = $cfg['sign'] ?? '';
|
|
$content = '【' . $sign . '】' . str_replace(
|
|
['{code}', '{mobile}'],
|
|
[$sms['code'] ?? '', $sms['mobile'] ?? ''],
|
|
$cfg['template'] ?? '您的验证码为:{code},请勿泄露给他人'
|
|
);
|
|
$params = [
|
|
'u' => $cfg['account'] ?? '',
|
|
'p' => $cfg['password'] ?? '',
|
|
'm' => $sms['mobile'],
|
|
'c' => $content,
|
|
];
|
|
|
|
try {
|
|
$client = new HttpClient();
|
|
$resp = $client->get($api, $params);
|
|
if ($resp === false) {
|
|
Log::error('[smssend] 请求失败: ' . $client->getError());
|
|
return false;
|
|
}
|
|
// 示例按短信宝协议判断:返回 "0" 表示成功,其余为错误码
|
|
$resp = trim((string) $resp);
|
|
if ($resp === '0') {
|
|
return true;
|
|
}
|
|
Log::error('[smssend] 网关返回异常: ' . $resp);
|
|
return false;
|
|
} catch (\Throwable $e) {
|
|
Log::error('[smssend] 发送异常: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通知类短信(可选实现)
|
|
*/
|
|
public function onNotice($sms): bool
|
|
{
|
|
return true;
|
|
}
|
|
}
|