mirror of
http://124.126.16.154:8888/singularity/HyperfDevelopmentKitCore.git
synced 2026-01-15 03:25:05 +08:00
feat(Email): 实现了邮件发送的事件机制
This commit is contained in:
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -2,6 +2,7 @@
|
|||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
<inspection_tool class="PhpCSFixerValidationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="PhpCSFixerValidationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PhpDocSignatureInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
<inspection_tool class="PhpPropertyOnlyWrittenInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="PhpPropertyOnlyWrittenInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PhpStanGlobal" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
<inspection_tool class="PhpStanGlobal" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
|
|||||||
76
docs/Email.md
Normal file
76
docs/Email.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Email | 邮件
|
||||||
|
提供一套通用 Service 用于定制需求,和一套现成的事件/监听器用于异步发送。
|
||||||
|
|
||||||
|
## 服务类
|
||||||
|
[\Singularity\HDK\Core\Service\EmailService](../src/Service/EmailService.php)
|
||||||
|
* 发送纯文本邮件的 `\Singularity\HDK\Core\Service\EmailService::sendText()`
|
||||||
|
* 发送 Html 富文本邮件的 `\Singularity\HDK\Core\Service\EmailService::sendHtml()`
|
||||||
|
|
||||||
|
## 事件机制
|
||||||
|
> 这种方式无法监听邮件发送的结果!
|
||||||
|
>
|
||||||
|
> 如果你需要根据邮件发送的结果进行处理,
|
||||||
|
> 请使用服务类进行自定义
|
||||||
|
|
||||||
|
更好的方法可能是在事件发生后触发异步队列,
|
||||||
|
但如果将异步队列封装在本包中,
|
||||||
|
相当于强制引用本库的项目使用异步队列机制,
|
||||||
|
这是我们不愿意看到的。
|
||||||
|
所以这里的监听器只是集成了同步发送的操作。
|
||||||
|
|
||||||
|
如果你想要定义更好的设计,
|
||||||
|
你可以直接使用提供的 Service 类进行定制。
|
||||||
|
> 或许这里还有优化空间😄
|
||||||
|
|
||||||
|
### 事件
|
||||||
|
[\Singularity\HDK\Core\Events\EmailWillSent](../src/Events/EmailWillSent.php)
|
||||||
|
### 监听器
|
||||||
|
[\Singularity\HDK\Core\Listener\EmailWillSentListener](../src/Listener/EmailWillSentListener.php)
|
||||||
|
### 使用方法
|
||||||
|
监听器已经通过 [ConfigProvider](../src/ConfigProvider.php) 机制注册,
|
||||||
|
所以你只需要在要发送邮件的地方调度这个事件即可。
|
||||||
|
> 这也就意味着,你无法调用这个事件,但不触发这个监听器。
|
||||||
|
> 如果你有这样做的必要,请创建一个自己的事件。
|
||||||
|
> 这也是为了保证功能的完整性和原子性。
|
||||||
|
|
||||||
|
具体使用方法,如下代码所示:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use App\Event\UserRegistered;use Singularity\HDK\Core\Events\EmailWillSent;
|
||||||
|
|
||||||
|
class UserService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
#[Inject]
|
||||||
|
private $eventDispatcher;
|
||||||
|
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
// 我们假设存在 User 这个实体
|
||||||
|
$user = new User();
|
||||||
|
$result = $user->save();
|
||||||
|
|
||||||
|
// ↓
|
||||||
|
// 这里 dispatch(object $event) 会逐个运行监听该事件的监听器
|
||||||
|
$this->eventDispatcher->dispatch(new EmailWillSent(
|
||||||
|
target: $user->mobile,
|
||||||
|
subject: '注册成功通知',
|
||||||
|
type: 'html', // 默认 text 可以不传
|
||||||
|
content: <<<HTML
|
||||||
|
<h1>恭喜你,注册成功!</h1>
|
||||||
|
HTML,
|
||||||
|
));
|
||||||
|
// ↑
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
@@ -14,6 +14,7 @@ namespace Singularity\HDK\Core;
|
|||||||
|
|
||||||
use Hyperf\Contract\StdoutLoggerInterface;
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
use Hyperf\Framework\Logger\StdoutLogger;
|
use Hyperf\Framework\Logger\StdoutLogger;
|
||||||
|
use Singularity\HDK\Core\Listener\EmailWillSentListener;
|
||||||
|
|
||||||
class ConfigProvider
|
class ConfigProvider
|
||||||
{
|
{
|
||||||
@@ -38,7 +39,9 @@ class ConfigProvider
|
|||||||
'commands' => [
|
'commands' => [
|
||||||
],
|
],
|
||||||
// 与 commands 类似
|
// 与 commands 类似
|
||||||
'listeners' => [],
|
'listeners' => [
|
||||||
|
EmailWillSentListener::class
|
||||||
|
],
|
||||||
// 组件默认配置文件,即执行命令后会把 source 的对应的文件复制为 destination 对应的的文件
|
// 组件默认配置文件,即执行命令后会把 source 的对应的文件复制为 destination 对应的的文件
|
||||||
'publish' => [
|
'publish' => [
|
||||||
[
|
[
|
||||||
|
|||||||
50
src/Events/EmailWillSent.php
Normal file
50
src/Events/EmailWillSent.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EmailWillSent.php@HDK-Core
|
||||||
|
*
|
||||||
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2023/1/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Core\Events\EmailWillSent@HDK-Core
|
||||||
|
*
|
||||||
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2023/1/16
|
||||||
|
*
|
||||||
|
* @link ../../docs/Email.md
|
||||||
|
*/
|
||||||
|
class EmailWillSent
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
/**
|
||||||
|
* @var string|string[] $target
|
||||||
|
*/
|
||||||
|
public string|array $target,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var non-empty-string $subject
|
||||||
|
*/
|
||||||
|
public string $subject,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var non-empty-string $content
|
||||||
|
*/
|
||||||
|
public string $content,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[] $cc
|
||||||
|
*/
|
||||||
|
public array $cc = [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var 'text'|'html' $type
|
||||||
|
*/
|
||||||
|
public string $type = 'text'
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
94
src/Listener/EmailWillSentListener.php
Normal file
94
src/Listener/EmailWillSentListener.php
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EmailWillSentListener.php@HDK-Core
|
||||||
|
*
|
||||||
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2023/1/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Singularity\HDK\Core\Listener;
|
||||||
|
|
||||||
|
use Hyperf\Contract\ContainerInterface;
|
||||||
|
use Hyperf\Contract\StdoutLoggerInterface;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
use Hyperf\Event\Contract\ListenerInterface;
|
||||||
|
use JetBrains\PhpStorm\NoReturn;
|
||||||
|
use Psr\Container\ContainerExceptionInterface;
|
||||||
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
|
use Singularity\HDK\Core\Constants\CommonErrorCode;
|
||||||
|
use Singularity\HDK\Core\Events\EmailWillSent;
|
||||||
|
use Singularity\HDK\Core\Service\EmailService;
|
||||||
|
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singularity\HDK\Core\Listener\EmailWillSentListener@HDK-Core
|
||||||
|
*
|
||||||
|
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||||
|
* Powered by PhpStorm
|
||||||
|
* Created on 2023/1/16
|
||||||
|
*
|
||||||
|
* @link ../../docs/Email.md
|
||||||
|
*/
|
||||||
|
class EmailWillSentListener implements ListenerInterface
|
||||||
|
{
|
||||||
|
#[Inject]
|
||||||
|
private ContainerInterface $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function listen(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
EmailWillSent::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EmailWillSent $event
|
||||||
|
* @return void
|
||||||
|
* @throws ContainerExceptionInterface
|
||||||
|
* @throws NotFoundExceptionInterface
|
||||||
|
*/
|
||||||
|
#[NoReturn]
|
||||||
|
public function process(object $event): void
|
||||||
|
{
|
||||||
|
$stdoutLogger = $this->container->get(StdoutLoggerInterface::class);
|
||||||
|
$emailService = $this->container->get(EmailService::class);
|
||||||
|
try {
|
||||||
|
$event->type === 'html'
|
||||||
|
? $emailService->sendHtml(
|
||||||
|
target: $event->target,
|
||||||
|
subject: $event->subject,
|
||||||
|
html: $event->content,
|
||||||
|
cc: $event->cc
|
||||||
|
)
|
||||||
|
: $emailService->sendText(
|
||||||
|
target: $event->target,
|
||||||
|
subject: $event->subject,
|
||||||
|
text: $event->content,
|
||||||
|
cc: $event->cc
|
||||||
|
);
|
||||||
|
|
||||||
|
$stdoutLogger->info('邮件发送成功!');
|
||||||
|
$stdoutLogger->info("To: $event->target");
|
||||||
|
$stdoutLogger->info("Subject: $event->subject");
|
||||||
|
$stdoutLogger->debug('Content: ');
|
||||||
|
$stdoutLogger->debug($event->content);
|
||||||
|
} catch (TransportExceptionInterface $e) {
|
||||||
|
$code = CommonErrorCode::SERVER_MESSAGE_EMAIL_ERROR;
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
if (strpos($msg, '500 Error: bad syntax')) {
|
||||||
|
$code = CommonErrorCode::SERVER_MESSAGE_EMAIL_NOT_FOUND;
|
||||||
|
$msg = CommonErrorCode::getMessage($code);
|
||||||
|
}
|
||||||
|
$stdoutLogger->alert('邮件发送失败!');
|
||||||
|
$stdoutLogger->error(
|
||||||
|
<<<ERROR_LOG
|
||||||
|
[$code] $msg
|
||||||
|
ERROR_LOG
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user