From 48bd60dc59942e7e8afe7b080f6f7c9f033c7132 Mon Sep 17 00:00:00 2001 From: chuan <2154243450@qq.com> Date: Fri, 18 Apr 2025 11:31:40 +0800 Subject: [PATCH] up --- app/admin/controller/Admin.php | 16 +--- app/admin/controller/Upload.php | 51 +++++------ app/admin/job/SendEmailFromBackend.php | 43 +++++++++ app/admin/job/SendSmsFromBackend.php | 51 +++++++++++ app/admin/route/app.php | 17 +--- app/admin/service/AdminService.php | 122 ++++--------------------- app/home/service/LoginService.php | 8 +- 7 files changed, 148 insertions(+), 160 deletions(-) create mode 100644 app/admin/job/SendEmailFromBackend.php create mode 100644 app/admin/job/SendSmsFromBackend.php diff --git a/app/admin/controller/Admin.php b/app/admin/controller/Admin.php index 361c8001..b9bdf4ca 100644 --- a/app/admin/controller/Admin.php +++ b/app/admin/controller/Admin.php @@ -148,7 +148,7 @@ class Admin extends AdminBaseController return json($returnData); } - // 一键推送消息,邮件或短信 + // 单次发送邮件或短信消息 public function sendEmailOrSms() { $returnData = (new AdminService())->sendEmailOrSms($this->request->param()); @@ -161,18 +161,4 @@ class Admin extends AdminBaseController $returnData = (new AdminService())->batchSendEmailOrSms($this->request->param()); return json($returnData); } - - // 定时任务执行 批量发送短信 - public function execBatchSendSms() - { - $returnData = (new AdminService())->execBatchSendSms(); - return json($returnData); - } - - // 定时任务窒执行 批量发送邮件 - public function execBatchSendEmail() - { - $returnData = (new AdminService())->execBatchSendEmail(); - return json($returnData); - } } diff --git a/app/admin/controller/Upload.php b/app/admin/controller/Upload.php index 915b43e4..a53fc5ae 100644 --- a/app/admin/controller/Upload.php +++ b/app/admin/controller/Upload.php @@ -239,19 +239,6 @@ class Upload extends AdminBaseController return json(['code' => 400, 'message' => '上传分片失败']); } - // 更新上传分片记录 - if (empty($awsS3->parts)) { - $buildParts = json_encode([ - ['PartNumber'=>trim($param['partNumber']), 'ETag'=>$result['ETag']] - ]); - $awsS3->parts = $buildParts; - } else { - $parsePart = json_decode($awsS3->parts, true); - $parsePart[] = ['PartNumber'=>trim($param['partNumber']), 'ETag'=>$result['ETag']]; - $awsS3->parts = json_encode($parsePart); - } - $awsS3->save(); - return json([ 'code' => 200, 'message' => 'success', @@ -276,20 +263,11 @@ class Upload extends AdminBaseController if (empty($param['uploadId'])) { return json(['code' => 400, 'message' => '缺少参数']); } - // 注意:$parts 是一个数组,里面需要有每个分段编号,以及每个分段对应的ETag -// $parts = [ -// ['PartNumber' => 1, 'ETag' => 'etag-for-part-1'], -// ['PartNumber' => 2, 'ETag' => 'etag-for-part-2'], -// ]; + // 获取分段上传记录信息 $awsS3 = AwsS3Model::where(['upload_id'=>trim($param['uploadId'])])->find(); - if (empty($awsS3) || empty($awsS3['parts']) || empty($awsS3['key'])) { + if (empty($awsS3) || empty($awsS3['key'])) { return json(['code' => 400, 'message' => 'uploadId对应的数据错误']); } - // 取出上传的分片记录,并排序 - $parts = json_decode($awsS3['parts'],true); - $partNumbers = array_column($parts, 'PartNumber'); - array_multisort($partNumbers, SORT_ASC, $parts); - // 初始化s3客户端 $s3Config = Config::get('common.aws_s3'); $s3Client = new S3Client([ @@ -300,16 +278,37 @@ class Upload extends AdminBaseController 'secret' => $s3Config['aws_secret'], ], ]); + // 获取已经上传的分片 + $getParts = $s3Client->listParts([ + 'Bucket' => $s3Config['aws_bucket'], + 'Key' => $awsS3['key'], + 'UploadId' => trim($param['uploadId']), + ]); + if (empty($getParts) || !isset($getParts['Parts'])) { + return json(['code' => 400, 'message' => '获取已上传的分片数据失败']); + } + // 按顺序组装分片数据 + $buildParts = []; + foreach ($getParts['Parts'] as $p) { + $buildParts[] = [ + 'PartNumber' => trim($p['PartNumber'], '"'), + 'ETag' => $p['ETag'] + ]; + } + $sortIndex = array_column($buildParts, 'PartNumber'); + array_multisort($sortIndex, SORT_ASC, $buildParts); + Log::info("升序排列后的分片数据:".json_encode($buildParts)); + + // 请求s3完成分段上传任务 $result = $s3Client->completeMultipartUpload([ 'Bucket' => $s3Config['aws_bucket'], 'Key' => $awsS3['key'], 'UploadId' => $param['uploadId'], 'MultipartUpload' => [ - 'Parts' => $parts + 'Parts' => $buildParts ], ])->toArray(); Log::info("完成分段上传结果:".json_encode($result)); - // 更新分片上传记录 $awsS3->is_complete = 1; $awsS3->s3_url = $result['Location']; diff --git a/app/admin/job/SendEmailFromBackend.php b/app/admin/job/SendEmailFromBackend.php new file mode 100644 index 00000000..87b513f4 --- /dev/null +++ b/app/admin/job/SendEmailFromBackend.php @@ -0,0 +1,43 @@ +sendEmail($data['email'], $data['title'], $data['content']); + if ($bool) { + $success = true; + break; + } + } + + // 任务失败 + if (!$success) { + trace($job->getJobId().'---管理端发送邮件任务失败-------'.json_encode($data), 'info'); + } + + // 删除任务 + $job->delete(); + } + + public function failed($data) + { + // 失败任务 + $dataStr = json_encode($data); + trace('queue job 任务失败---'.$dataStr, 'error'); + } +} \ No newline at end of file diff --git a/app/admin/job/SendSmsFromBackend.php b/app/admin/job/SendSmsFromBackend.php new file mode 100644 index 00000000..c898bff0 --- /dev/null +++ b/app/admin/job/SendSmsFromBackend.php @@ -0,0 +1,51 @@ + $conArr[0], + 'secret' => $conArr[1] + ]; + } + return $config; + } + + /** + * @desc 发送短信验证码 + * @param Job $job + * @param $data + * @return void + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function fire(Job $job, $data) + { + trace($job->getJobId().'---管理端发送短信任务开始--------'.json_encode($data), 'info'); + $to = $data['mobile']; + $message = $data['message']; + $from = 'Bourse'; + $accessKey = env('SMS.ACCESS_KEY_ID'); + $secret = env('SMS.ACCESS_KEY_SECRET'); + if (empty($accessKey) || empty($secret)) { + trace('------- 短信账号配置错误 -------', 'error'); + return; + } + (new \app\utility\SendSms())->sendMessageToGlobe($to, $message, $from, $accessKey, $secret); + // 删除任务 + $job->delete(); + } + +} \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index 2e1c555f..74f16a6f 100644 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -28,8 +28,11 @@ Route::group('/', function () { Route::post('config/sms_template_list', 'Config/smsTemplateList'); //获取短信模板列表 Route::post('config/edit_sms_template', 'Config/editSmsTemplate'); //编辑短信模板 + // 消息推送 Route::post('notice/popup', 'Notice/popUp'); // 弹窗推送消息 - Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送系统级通知 + Route::post('notice/push_message', 'Notice/pushMessage'); // 使用Pusher推送系统级消息 + Route::post('admin/send_email_or_sms', 'Admin/sendEmailOrSms'); // 给用户发邮件或者短信 + Route::post('admin/batch_send_email_or_sms', 'Admin/batchSendEmailOrSms'); // 批量给用户发邮件或者短信 // 渠道列表 Route::post('/channel/list', 'Channel/list'); //渠道列表 @@ -52,6 +55,7 @@ Route::group('/', function () { Route::post('add_video', 'video/addVideoOnDemand')->middleware('admin_log'); //添加点播视频 Route::post('edit_video', 'video/editVideoOnDemand')->middleware('admin_log'); //编辑点播视频 + // 直播间管理 Route::post('video/blocked_word_list', 'Video/blockedWordList'); //屏蔽词列表 Route::post('video/blocked_word_add', 'Video/blockedWordAdd')->middleware('admin_log'); //添加屏蔽词 Route::post('video/blocked_word_edit', 'Video/blockedWordEdit')->middleware('admin_log'); //编辑屏蔽词 @@ -219,10 +223,6 @@ Route::group('/', function () { // 送会员 Route::post('admin/give_vip', 'Admin/giveVip')->middleware('admin_log'); //赠送用户vip - Route::post('admin/send_email_or_sms', 'Admin/sendEmailOrSms'); // 给用户发邮件或者短信 - Route::post('admin/batch_send_email_or_sms', 'Admin/batchSendEmailOrSms'); // 批量给用户发邮件或者短信 - Route::post('admin/exec_batch_send_sms', 'Admin/execBatchSendSms'); // 定时任务执行 - 批量发送短信 - Route::post('admin/exec_batch_send_email', 'Admin/execBatchSendEmail'); // 定时任务执行 - 批量发送邮件 // 配置管理 // 外汇插针行情 @@ -521,12 +521,10 @@ Route::group('/', function () { Route::post('/setting/block_stock_add', 'setting.BlockStock/add')->middleware('admin_log'); Route::post('/setting/block_stock_edit', 'setting.BlockStock/edit')->middleware('admin_log'); - // 股票指数 Route::post('/setting/stock_index_list', 'setting.StockIndex/index'); Route::post('/setting/stock_index_update', 'setting.StockIndex/update'); - // 资金管理 Route::post('/flow/digital', 'Flow/digital'); Route::post('/flow/stock', 'Flow/stock'); @@ -553,14 +551,9 @@ Route::group('/', function () { Route::post('/flow/block_stock', 'Flow/blockStock'); //股票大宗流水 Route::post('flow/inr_stock_index', 'Flow/inrStockIndex'); //印度股指资产流水 - - Route::post('/flow/fund_stock', 'Flow/fundStock'); - Route::post('/flow/in_option_stock', 'Flow/inOptionStock'); - - // 充值订单 Route::post('/recharge/index', 'Recharge/index'); // 充值订单 Route::post('/recharge/info', 'Recharge/info'); diff --git a/app/admin/service/AdminService.php b/app/admin/service/AdminService.php index d1d20a96..14014eea 100644 --- a/app/admin/service/AdminService.php +++ b/app/admin/service/AdminService.php @@ -22,17 +22,13 @@ use think\exception\ValidateException; use app\utility\UnqId; use think\facade\Db; use think\facade\Log; +use think\facade\Queue; use function Sodium\compare; use think\facade\Request; class AdminService extends AdminBaseService { - const BATCH_SMS_LIST_KEY = "BATCH_SMS_LIST_KEY"; // 批量发送短信redis Key - const BATCH_SMS_CONTENT_KEY = "BATCH_SMS_CONTENT_KEY"; // 批量发送短信内容Key - const BATCH_EMAIL_LIST_KEY = "BATCH_EMAIL_LIST_KEY"; // 批量发送邮件redis Key - const BATCH_EMAIL_CONTENT_KEY = "BATCH_EMAIL_CONTENT_KEY"; // 邮件内容redis key - // 根据角色获取账号列表 public function getUsersByRole($param) { @@ -879,6 +875,7 @@ class AdminService extends AdminBaseService } } + // 单次发送邮件或短信 public function sendEmailOrSms($param) { try { @@ -956,37 +953,41 @@ class AdminService extends AdminBaseService switch ($param['type']) { case 1: // 发送短信 - $userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('phone_number', 'user_id'); + $userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('phone_number,country_code', 'user_id'); if (empty($userList)) { return $this->toData('500', '用户列表为空'); } - // 将短信内容存储在redis中 - Cache::store('redis')->set(self::BATCH_SMS_CONTENT_KEY, $param['content']); - // 将用户手机号存储到redis list中 - foreach ($userList as $phone) { - if (empty($phone)) { + // 循环将每个用户发送短信任务加入到队列 + foreach ($userList as $v) { + if (empty($v)) { continue; } - Cache::store('redis')->lpush(self::BATCH_SMS_LIST_KEY, $phone); + $jobName = 'app\admin\job\SendSmsFromBackend'; + Queue::push($jobName, [ + 'mobile' => $v['country_code'].$v['phone_number'], + 'message' => $param['content'], + ], 'sendSmsFromBackend'); } break; case 2: // 发送邮件 if (empty($param['title'])) { return $this->toData('400', '邮件标题不能为空'); } - $userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('email', 'user_id'); + $userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('email'); if (empty($userList)) { return $this->toData('500', '用户列表为空'); } - // 将邮件内容存储在redis中 - $buildContent = $param['title']."@".$param['content']; - Cache::store('redis')->set(self::BATCH_EMAIL_CONTENT_KEY, $buildContent); - // 将用邮箱存储到redis list中 + // 循环将每个用户发送邮件任务加入到队列 foreach ($userList as $email) { if (empty($email)) { continue; } - Cache::store('redis')->lpush(self::BATCH_EMAIL_LIST_KEY, $email); + $jobName = 'app\admin\job\SendEmailFromBackend'; + Queue::push($jobName, [ + 'email' => $email, + 'title' => $param['title'], + 'content' => $param['content'], + ], 'sendEmailFromBackend'); } break; default: @@ -999,89 +1000,4 @@ class AdminService extends AdminBaseService } } - // 定时任务处理匹批量发送短信 - public function execBatchSendSms() - { - try { - // 每次处理2000个用户 - $maxNum = 2000; - $smsLen = Cache::store('redis')->llen(self::BATCH_SMS_LIST_KEY); - if ($smsLen <= 0) { - return; - } - if ($smsLen < $maxNum) { - $maxNum = $smsLen; - } - $accessKey = env('SMS.ACCESS_KEY_ID'); - $secret = env('SMS.ACCESS_KEY_SECRET'); - if (empty($accessKey) || empty($secret)) { - Log::info("批量短信发送 - 短信配置数据未找到"); - return; - } - $content = Cache::store('redis')->get(self::BATCH_SMS_CONTENT_KEY); - if (empty($content)) { - Log::info("批量短信发送 - 短信内容不能为空"); - return; - } - $smsObj = new \app\utility\SendSms(); - for ($i=1; $i<=$maxNum; $i++) { - $phone = Cache::store('redis')->rpop(self::BATCH_SMS_LIST_KEY); - if (empty($phone)) { - continue; - } - $from = 'Auto'; - $bool = $smsObj->sendMessageToGlobe($phone, $content, $from, $accessKey, $secret); - if (!$bool) { - Log::info("批量短信发送 - 当前用户发送失败, phone=".$phone); - } - } - return $this->toData('0', 'ok'); - } catch (\Exception $e) { - Log::info("批量短信发送异常:err==". $e->getMessage()." trace==".$e->getTraceAsString()); - return $this->toData('500', 'The system is busy', [$e->getMessage(), $e->getTrace()]); - } - } - - // 定时任务执行批量发送邮件任务 - public function execBatchSendEmail(){ - try { - // 每次处理2000个用户 - $maxNum = 2000; - $emailLen = Cache::store('redis')->llen(self::BATCH_EMAIL_LIST_KEY); - if ($emailLen <= 0) { - return; - } - if ($emailLen < $maxNum) { - $maxNum = $emailLen; - } - $content = Cache::store('redis')->get(self::BATCH_EMAIL_CONTENT_KEY); - if (empty($content)) { - Log::info("批量邮件发送 - 邮件内容不能为空"); - return; - } - // 邮件内容需要以@符号分割,然后获取到title 和 content - $splStr = explode('@', $content); - $title = $splStr[0]; - $msg = $splStr[1]; - $phpEmail = new \app\utility\SendEmail(); - for ($i=1; $i<=$maxNum; $i++) { - $email = Cache::store('redis')->rpop(self::BATCH_EMAIL_LIST_KEY); - if (empty($email)) { - continue; - } - $emailTemplate['email'] = $email; - $title = trim($title); - $content = trim($msg); - $bool = $phpEmail->sendEmail($emailTemplate['email'], $title, $content); - if (!$bool) { - Log::info("批量发送邮件 - 当前用户发送失败, email=".$email); - } - } - return $this->toData('0', 'ok'); - } catch (\Exception $e) { - Log::info("批量短信发送异常:err==". $e->getMessage()." trace==".$e->getTraceAsString()); - return $this->toData('500', 'The system is busy', [$e->getMessage(), $e->getTrace()]); - } - } - } diff --git a/app/home/service/LoginService.php b/app/home/service/LoginService.php index 1c7d4fb4..cf905554 100644 --- a/app/home/service/LoginService.php +++ b/app/home/service/LoginService.php @@ -457,9 +457,9 @@ class LoginService extends BaseHomeService $this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay); // 校验验证码 + $mobile = $param['nation'] . $param['phone']; + $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile; if ($param['sms_code'] != 8888) { // 方便测试,8888为万能验证码 - $mobile = $param['nation'] . $param['phone']; - $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile; if (!$this->checkCode($smsKey, $param['sms_code'])) { return $this->toData('100300', 'The verification code is incorrect.', []); //注册验证码 @@ -658,9 +658,9 @@ class LoginService extends BaseHomeService $param['phone'] = trim($param['phone']); // 验证短信验证码 + $mobile = $param['nation'] . $param['phone']; + $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile; if ($param['sms_code'] != 8888) { - $mobile = $param['nation'] . $param['phone']; - $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile; if (!$this->checkCode($smsKey, $param['sms_code'])) { return $this->toData('100300', 'The verification code is incorrect.', []); };