作者 赵彬吉

订阅邮件

<?php
namespace App\Console\Commands\Task;
use App\Mail\TextMail;
use App\Models\Subscribe\GroupSendTask;
use App\Models\Subscribe\GroupSendTaskLog;
use App\Models\Subscribe\Smtp;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
/**
*
* Class TaskDistribution
* @package App\Console\Commands
* @author zbj
* @date 2023/11/28
*/
class EmailGroupSend extends Command
{
protected $signature = 'email_group_send_task';
protected $description = '邮件群发任务';
public function handle()
{
while (true) {
$tasks = GroupSendTask::where('status', GroupSendTask::STATUS_PENDING)->where('send_time', '<=', time())->get();
if (!$tasks->count()) {
sleep(10);
}
foreach ($tasks as $task) {
$this->toQueue($task);
}
}
}
public function toQueue(GroupSendTask $task)
{
$this->output('开始执行任务:' . $task->id);
$smtp_config = Smtp::where('project_id', $task->project_id)->first();
if (!$smtp_config) {
$task->status = GroupSendTask::STATUS_ERROR;
$task->remark = '未配置SMTP';
$task->save();
$this->output('任务:' . $task->id . '失败,未配置SMTP');
return false;
}
Config::set('mail.mailers.smtp.host', $smtp_config['host']);
Config::set('mail.mailers.smtp.username', $smtp_config['email']);
Config::set('mail.mailers.smtp.password', $smtp_config['password']);
Config::set('mail.from.address', $smtp_config['email']);
Config::set('mail.from.name', $smtp_config['from_name']);
foreach ($task->emails as $email) {
try {
Mail::to([$email])->send(new TextMail(['subject' => $task->subject, 'text' => $task->text]));
GroupSendTaskLog::addLog($task->id, $task->project_id, $smtp_config['email'], $email);
} catch (\Exception $e) {
GroupSendTaskLog::addLog($task->id, $task->project_id, $smtp_config['email'], $email, 2, $e->getMessage());
$this->output('任务:' . $task->id . ' 邮箱' . $email . '发送失败,' . $e->getMessage());
}
}
$task->status = GroupSendTask::STATUS_SUCCESS;
$task->save();
}
/**
* 输出处理日志
*/
public function output($message): bool
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
return true;
}
}
... ...
... ... @@ -15,6 +15,7 @@ use App\Models\RouteMap\RouteMap;
use App\Models\User\ProjectMenu as ProjectMenuModel;
use App\Models\User\ProjectRole as ProjectRoleModel;
use App\Models\User\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
/***
... ... @@ -109,6 +110,10 @@ class ComController extends BaseController
if($projectCode != 1){
$info['role_menu'] = trim(str_replace(',50,',',',','.$info['role_menu'].','),',');
}
$is_subscribe = $this->getIsSubscribe();
if(!$is_subscribe){
$info['role_menu'] = trim(str_replace(',52,',',',','.$info['role_menu'].','),',');
}
$this->map = [
'status'=>0,
'is_role'=>0,
... ... @@ -217,6 +222,11 @@ class ComController extends BaseController
return 0;
}
public function getIsSubscribe(){
return $this->project['is_subscribe'];
}
/**
* @name :登录用户编辑资料/修改密码
* @author :liyuhang
... ...
... ... @@ -26,6 +26,7 @@ class BaseController extends Controller
protected $map = [];//处理后的参数
protected $uid = 0;
protected $user = [];//当前登录用户详情
protected $project = [];//当前登录项目详情
/**
* ceshi获取所有参数
*/
... ...
<?php
namespace App\Http\Controllers\Bside\Subscribe;
use App\Enums\Common\Code;
use App\Helper\Arr;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Inquiry\InquiryLogic;
use App\Models\Inquiry\InquiryForm;
use App\Models\Subscribe\Email;
use App\Models\Subscribe\GroupSendTask;
use App\Models\Subscribe\Smtp;
use App\Rules\Ids;
use App\Services\BatchExportService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
/**
* 订阅邮件管理
* Class EmailController
* @package App\Http\Controllers\Bside\Subscribe
* @author zbj
* @date 2024/8/29
*/
class EmailController extends BaseController
{
public function list(Email $emailModel)
{
$lists = $emailModel->lists($this->map, $this->page, $this->row);
$this->response('success', Code::SUCCESS, $lists);
}
public function delete(Email $emailModel)
{
$this->request->validate([
'id' => 'required',
], [
'id.required' => 'id不为空',
]);
$emailModel->del(['id' => $this->param['id']]);
$this->response('success');
}
public function export(Email $emailModel)
{
$data = $emailModel->list([], 'id', ['*'], 'desc', 1000);
//生成文件,发送到客户端
$map = [
'email' => '邮箱',
'created_at' => '订阅时间',
];
$table = new BatchExportService("订阅邮箱导出");
$file = $table->head($map)->data($data)->save();
if (!$file) {
throw new \Exception('文件生成失败,请重试');
}
$fileurl = Storage::disk('runtime')->url($file);
$this->response('success', Code::SUCCESS, ['url' => $fileurl]);
}
public function set_smtp(Smtp $smtp)
{
$this->request->validate([
'project_id' => ['required'],
'email' => ['required', 'email', 'max:200'],
'password' => ['required', 'max:200'],
'host' => ['required', 'max:200', 'regex:/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/'],
'from_name' => ['required', 'max:200'],
], [
'project_id.required' => '参数异常',
'email.required' => '邮箱必须',
'email.email' => '邮箱格式错误',
'password.required' => '授权码/密码必须',
'host.required' => 'smtp地址必须',
'host.regex' => 'smtp格式错误',
'from_name.required' => '发信人昵称必须',
]);
$info = $smtp->read(['project_id' => $this->param['project_id']]);
if (!$info) {
$smtp->add($this->param);
} else {
$smtp->edit($this->param, ['project_id' => $this->param['project_id']]);
}
$this->response('success');
}
public function group_send(GroupSendTask $groupSendTask)
{
$this->request->validate([
'project_id' => ['required'],
'emails' => ['required'],
'subject' => ['required'],
'text' => ['required'],
], [
'project_id.required' => '参数异常',
'emails.required' => '发送对象必须',
'subject.required' => '邮件主题必须',
'host.required' => 'smtp地址必须',
]);
if($this->param['send_time'] && !strtotime($this->param['send_time'])){
$this->fail('发送时间格式错误',Code::USER_ERROR);
}
$smtp = new Smtp();
$info = $smtp->read(['project_id' => $this->param['project_id']]);
if(!$info){
$this->fail('请先设置SMTP',Code::USER_ERROR);
}
$this->param['emails'] = Arr::a2s($this->param['emails']);
$this->param['send_time'] = empty($this->param['send_time']) ? 0 : strtotime($this->param['send_time']);
$this->param['user_id'] = $this->user['id'];
$groupSendTask->add($this->param);
$this->response('success');
}
}
... ...
... ... @@ -191,6 +191,7 @@ class UserLoginLogic
}
$info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority'];
$info['is_inquiry_country'] = $project['is_inquiry_country'];
$info['is_subscribe'] = $project['is_subscribe'];
//是否开通AMP
$is_amp = 0;
if(!empty($project['deploy_optimize']['domain'])){
... ... @@ -299,6 +300,7 @@ class UserLoginLogic
}
$info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority'];
$info['is_inquiry_country'] = $project['is_inquiry_country'];
$info['is_subscribe'] = $project['is_subscribe'];
//是否开通AMP
$is_amp = 0;
if(!empty($project['deploy_optimize']['domain'])){
... ...
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class TextMail extends Mailable
{
use Queueable, SerializesModels;
protected string $text;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($data)
{
$this->subject = $data['subject'];
$this->text = $data['text'];
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->subject($this->subject)->view('mail.text', ['text' => $this->text]);
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Email
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class Email extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $connection = "custom_mysql";
protected $table = 'gl_subscribe_email';
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Helper\Arr;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class GroupSendTask
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class GroupSendTask extends Base
{
use SoftDeletes;
const STATUS_PENDING = 0;
const STATUS_QUEUE = 1;
const STATUS_SUCCESS = 2;
const STATUS_ERROR = 9;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_group_send_task';
// public function setEmailsAttribute($value){
// $this->attributes['emails'] = Arr::a2s($value);
// }
public function getEmailsAttribute($value){
return Arr::s2a($value);
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class GroupSendTaskLog
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class GroupSendTaskLog extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_group_send_task_log';
//`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
// `task_id` int(11) unsigned NOT NULL DEFAULT '0',
// `project_id` int(11) unsigned NOT NULL DEFAULT '0',
// `from` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
// `to` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
// `status` tinyint(1) unsigned NOT NULL DEFAULT '0',
// `manage_id` int(11) unsigned NOT NULL DEFAULT '0',
// `created_at` datetime NOT NULL,
// `updated_at` datetime NOT NULL,
// `deleted_at` datetime DEFAULT NULL,
// `remark` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
public static function addLog($task_id, $project_id, $from, $to, $status = 1, $remark = '')
{
$model = new self();
$model->task_id = $task_id;
$model->project_id = $project_id;
$model->from = $from;
$model->to = $to;
$model->status = $status;
$model->remark = $remark;
$model->save();
}
}
... ...
<?php
namespace App\Models\Subscribe;
use App\Models\Base;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Smtp
* @package App\Models\Subscribe
* @author zbj
* @date 2024/8/27
*/
class Smtp extends Base
{
use SoftDeletes;
//设置关联表名
/**
* @var mixed
*/
protected $table = 'gl_email_smtp';
}
... ...
... ... @@ -8,8 +8,10 @@ use App\Models\Inquiry\InquiryForm;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Project\InquiryFilterConfig;
use App\Models\Project\Project;
use App\Models\Subscribe\Email;
use App\Models\SyncSubmitTask\SyncSubmitTask;
use App\Models\Visit\Visit;
use App\Utils\LogUtils;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
... ... @@ -52,6 +54,20 @@ class SyncSubmitTaskService
}
$action = $task['type'];
//是否是订阅邮箱
if($action == 'inquiry' && !empty($project['is_subscribe'])){
//是否只有email字段
$filed = '';
foreach ($data['data']['data'] as $k => $v){
if(Str::startsWith(strtolower($k),'globalso-')){
continue;
}
$filed .= $k;
}
$filed == 'email' && $action = 'subscribe';
}
$handler = new self();
return $handler->$action($data, $date);
}
... ... @@ -75,7 +91,25 @@ class SyncSubmitTaskService
return $referer;
}
/**
*
* 订阅邮箱
* @param $data
* @param $date
* @throws InquiryFilterException
* @author zbj
* @date 2024/8/27
*/
public function subscribe($data, $date){
$email = $data['data']['data']['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$model = new Email();
$model->email = $email;
$model->save();
}else{
throw new InquiryFilterException( '邮箱格式异常:' . $email);
}
}
/**
* 询盘
... ... @@ -87,7 +121,6 @@ class SyncSubmitTaskService
*/
public function inquiry($data, $date)
{
$this->inquiryFilter($data['project_id'], $data);
//数组key转为小写
... ...
... ... @@ -608,6 +608,15 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/getInfo', [\App\Http\Controllers\Bside\BCom\OperationHeartbeatController::class, 'getInfo'])->name('operation_heartbeat_getInfo');
});
//订阅邮件管理
Route::prefix('subscribe')->group(function () {
Route::any('/', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'list'])->name('subscribe_email_list');
Route::any('/del', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'delete'])->name('subscribe_email_del');
Route::any('/export', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'export'])->name('subscribe_email_export');
Route::any('/set_smtp', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'set_smtp'])->name('subscribe_email_set_smtp');
Route::any('/group_send', [\App\Http\Controllers\Bside\Subscribe\EmailController::class, 'group_send'])->name('subscribe_email_group_send');
});
});
//无需登录验证的路由组
Route::group([], function () {
... ...