535 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			535 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
<?php
 | 
						||
 | 
						||
namespace app\traits\account;
 | 
						||
 | 
						||
use app\exception\RepositoryException;
 | 
						||
use app\service\ali\Sms;
 | 
						||
use app\service\wx\WechatApplets;
 | 
						||
use app\validate\MessageValidate;
 | 
						||
use Exception;
 | 
						||
use GuzzleHttp\Exception\GuzzleException;
 | 
						||
use app\model\{Account, Config, Message, MessageLog, SmsLog};
 | 
						||
use app\exception\TraitException;
 | 
						||
use think\Collection;
 | 
						||
use think\facade\Log;
 | 
						||
use think\Model;
 | 
						||
use think\Validate;
 | 
						||
 | 
						||
/**
 | 
						||
 * 用户消息
 | 
						||
 *
 | 
						||
 * Trait MessageTrait
 | 
						||
 * @package app\traits\account
 | 
						||
 */
 | 
						||
trait AccountMessageTrait
 | 
						||
{
 | 
						||
    /**
 | 
						||
     * 消息类型文本描述
 | 
						||
     * @return string[]
 | 
						||
     */
 | 
						||
    public function messageTypeTextList(): array
 | 
						||
    {
 | 
						||
        return Message::typeTextList();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 目标人群文本描述
 | 
						||
     * @return string[]
 | 
						||
     */
 | 
						||
    public function messageTargetTextList(): array
 | 
						||
    {
 | 
						||
        return Message::targetTextList();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取消息列表
 | 
						||
     *
 | 
						||
     * @param  array  $where
 | 
						||
     * @param  array  $fields
 | 
						||
     * @param  int  $page
 | 
						||
     * @param  int  $size
 | 
						||
     * @param  callable|null  $callback
 | 
						||
     * @param  array  $orders
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public function messageList(array $where = [], array $fields = [], int $page = 1, int $size = 10, callable $callback = null, array $orders = []): array
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            return Message::findList($where, $fields, $page, $size, $callback, $orders);
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return [
 | 
						||
                'total'   => 0,
 | 
						||
                'current' => $page,
 | 
						||
                'size'    => $size,
 | 
						||
                'list'    => new Collection(),
 | 
						||
            ];
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 消息详情
 | 
						||
     *
 | 
						||
     * @param  int  $messageId
 | 
						||
     * @param  array  $fields
 | 
						||
     * @return null
 | 
						||
     */
 | 
						||
    public function messageInfo(int $messageId, array $fields = [])
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            return Message::findById($messageId, $fields);
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return null;
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取已读消息记录
 | 
						||
     * @param  int  $accountId
 | 
						||
     * @param  array  $messageIds
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public function getHadReadMessageIds(int $accountId, array $messageIds): array
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            $hadItems = MessageLog::whereIn('message_id', $messageIds)
 | 
						||
                ->where('account_id', $accountId)
 | 
						||
                ->select();
 | 
						||
 | 
						||
            return $hadItems->column('message_id');
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return [];
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 添加阅读记录
 | 
						||
     *
 | 
						||
     * @param  int  $accountId
 | 
						||
     * @param  array  $messageIds
 | 
						||
     * @return bool
 | 
						||
     */
 | 
						||
    public function addReadLogs(int $accountId, array $messageIds): bool
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            $readMsgIds   = $this->getHadReadMessageIds($accountId, $messageIds);
 | 
						||
            $newLogMsgIds = array_diff($messageIds, $readMsgIds);
 | 
						||
 | 
						||
            if ($newLogMsgIds) {
 | 
						||
                $newLogs = [];
 | 
						||
                foreach ($newLogMsgIds as $msgId) {
 | 
						||
                    $newLogs[] = [
 | 
						||
                        'message_id' => $msgId,
 | 
						||
                        'account_id' => $accountId,
 | 
						||
                        'created_at' => date('Y-m-d H:i:s'),
 | 
						||
                    ];
 | 
						||
                }
 | 
						||
                MessageLog::insertAll($newLogs);
 | 
						||
            }
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
 | 
						||
        return true;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 统计用户未读消息数量
 | 
						||
     *
 | 
						||
     * @param  int  $accountId
 | 
						||
     * @return int
 | 
						||
     */
 | 
						||
    public function countUnReadMessage(int $accountId): int
 | 
						||
    {
 | 
						||
        $unReadCount = 0;
 | 
						||
        try {
 | 
						||
            $regTime = '';
 | 
						||
            $account = Account::findById($accountId);
 | 
						||
            if ($account) {
 | 
						||
                $regTime = $account['created_at'];
 | 
						||
            }
 | 
						||
 | 
						||
            $allCount = Message::whereTime('send_at', '<=', date('Y-m-d H:i:s'))
 | 
						||
                ->when(!empty($regTime), function ($q2) use ($regTime) {
 | 
						||
                    $q2->whereTime('send_at', '>=', $regTime);
 | 
						||
                })
 | 
						||
                ->where(function ($q2) use ($accountId) {
 | 
						||
                    $q2->whereRaw('(target = "part" and find_in_set("'.$accountId.'", target_list)) or target <> "part"');
 | 
						||
                })
 | 
						||
                ->count();
 | 
						||
 | 
						||
            $readCount = MessageLog::where('account_id', $accountId)
 | 
						||
                ->when(!empty($regTime), function ($q2) use ($regTime) {
 | 
						||
                    $q2->whereTime('created_at', '>=', $regTime);
 | 
						||
                })
 | 
						||
                ->distinct(true)
 | 
						||
                ->field(['message_id'])
 | 
						||
                ->count();
 | 
						||
 | 
						||
            $unReadCount = $allCount - $readCount;
 | 
						||
            $unReadCount = $unReadCount > 0 ? $unReadCount : 0;
 | 
						||
        } catch (Exception $e) {
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        return $unReadCount;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 创建消息
 | 
						||
     *
 | 
						||
     * @param  string  $type  类型 ['system'|'notice']
 | 
						||
     * @param  string  $target  目标人群 ['all'| 'part']
 | 
						||
     * @param  array  $targetList  消息目标人群ID, $target='part' 时启用 []表示发送所有人
 | 
						||
     * @param  array  $messageData  消息内容 ['title' 标题|'summary' 概述|'content' 详情|'send_at' 发送时间]
 | 
						||
     * @return Message|Model
 | 
						||
     * @throws TraitException
 | 
						||
     */
 | 
						||
    public function addMessage(string $type, string $target, array $targetList = [], array $messageData = [])
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            if (!in_array($type, array_keys(Message::typeTextList()))) {
 | 
						||
                throw new TraitException('消息类型错误, 无此选项');
 | 
						||
            }
 | 
						||
            if (!in_array($target, array_keys(Message::targetTextList()))) {
 | 
						||
                throw new TraitException('目标人群错误, 无此选项');
 | 
						||
            }
 | 
						||
            $targetList = array_filter($targetList);
 | 
						||
            if ($target == Message::TARGET_PART && empty($targetList)) {
 | 
						||
                throw new TraitException('目标人群为部分接收时必须指定消息接收人员列表');
 | 
						||
            }
 | 
						||
            if ($target == Message::TARGET_ALL) {
 | 
						||
                $targetList = [];
 | 
						||
            }
 | 
						||
 | 
						||
            $validate = new MessageValidate();
 | 
						||
            if (!$validate->scene('add')->check($messageData)) {
 | 
						||
                throw new TraitException($validate->getError());
 | 
						||
            }
 | 
						||
 | 
						||
            $dataFields  = [
 | 
						||
                'title', 'summary', 'content', 'send_at', 'is_push',
 | 
						||
                'to_subscribe', 'to_sms', 'subscribe_data', 'sms_data', 'subscribe_temp_id', 'sms_temp_id'
 | 
						||
            ];
 | 
						||
            $messageData = arrayKeysFilter($messageData, $dataFields);
 | 
						||
 | 
						||
            $messageData['send_at']     = empty($messageData['send_at'] ?? '') ? date('Y-m-d H:i:s') : $messageData['send_at'];
 | 
						||
            $messageData['created_at']  = date('Y-m-d H:i:s');
 | 
						||
            $messageData['type']        = $type;
 | 
						||
            $messageData['target']      = $target;
 | 
						||
            $messageData['target_list'] = empty($targetList) ? '' : implode(',', $targetList);
 | 
						||
 | 
						||
            return Message::create($messageData);
 | 
						||
 | 
						||
        } catch (TraitException $e) {
 | 
						||
            throw $e;
 | 
						||
        } catch (Exception $e) {
 | 
						||
            Log::error('消息创建失败:'.$e->getMessage().' file:'.$e->getFile().' line:'.$e->getLine());
 | 
						||
            throw new TraitException('消息创建失败');
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 编辑消息
 | 
						||
     *
 | 
						||
     * @param  int  $id  消息ID
 | 
						||
     * @param  string  $type  类型 ['system'|'notice']
 | 
						||
     * @param  string  $target  目标人群 ['all'| 'part']
 | 
						||
     * @param  array  $targetList  消息目标人群ID, $target='part' 时启用
 | 
						||
     * @param  array  $messageData  消息内容 ['title' 标题|'summary' 概述|'content' 详情|'send_at' 发送时间]
 | 
						||
     * @return Message
 | 
						||
     * @throws TraitException
 | 
						||
     */
 | 
						||
    public function editMessage(int $id, string $type, string $target, array $targetList = [], array $messageData = [])
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            if (!in_array($type, array_keys(Message::typeTextList()))) {
 | 
						||
                throw new TraitException('消息类型错误, 无此选项');
 | 
						||
            }
 | 
						||
            if (!in_array($target, array_keys(Message::targetTextList()))) {
 | 
						||
                throw new TraitException('目标人群错误, 无此选项');
 | 
						||
            }
 | 
						||
            $targetList = array_filter($targetList);
 | 
						||
            if ($target == Message::TARGET_PART && empty($targetList)) {
 | 
						||
                throw new TraitException('目标人群为部分接收时必须指定消息接收人员列表');
 | 
						||
            }
 | 
						||
            if ($target == Message::TARGET_ALL) {
 | 
						||
                $targetList = [];
 | 
						||
            }
 | 
						||
 | 
						||
            $msg = Message::findById($id);
 | 
						||
            if (empty($msg)) {
 | 
						||
                throw new TraitException('没有相关的消息记录');
 | 
						||
            }
 | 
						||
 | 
						||
            $validate = new MessageValidate();
 | 
						||
            if (!$validate->scene('edit')->check($messageData)) {
 | 
						||
                throw new TraitException($validate->getError());
 | 
						||
            }
 | 
						||
 | 
						||
            $dataFields  = ['title', 'summary', 'content', 'send_at'];
 | 
						||
            $messageData = arrayKeysFilter($messageData, $dataFields);
 | 
						||
 | 
						||
            if (isset($messageData['send_at']) && empty($messageData['send_at'])) {
 | 
						||
                unset($messageData['send_at']);
 | 
						||
            }
 | 
						||
            $messageData['updated_at']  = date('Y-m-d H:i:s');
 | 
						||
            $messageData['type']        = $type;
 | 
						||
            $messageData['target']      = $target;
 | 
						||
            $messageData['target_list'] = empty($targetList) ? '' : implode(',', $targetList);
 | 
						||
 | 
						||
            return Message::where('id', $id)->update($messageData);
 | 
						||
        } catch (TraitException $e) {
 | 
						||
            throw $e;
 | 
						||
        } catch (Exception $e) {
 | 
						||
            throw new TraitException('消息更新失败');
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 删除消息记录
 | 
						||
     *
 | 
						||
     * @param  array  $ids
 | 
						||
     * @return bool
 | 
						||
     */
 | 
						||
    public function deleteMessages(array $ids): bool
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            Message::deleteByIds($ids);
 | 
						||
            // 删除关联的阅读记录
 | 
						||
            MessageLog::whereIn('message_id', $ids)->delete();
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
        return true;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 发送预约审核的订阅消息
 | 
						||
     *
 | 
						||
     * 注1:订阅消息需要在用户预约后订阅成功后才能发送,每次订阅只能推送一条订阅消息;
 | 
						||
     * 注2:用户取消订阅后无法下发订阅消息
 | 
						||
     * 注3:$msgData 参数格式必须严格按照消息模板字段的格式限制填写
 | 
						||
     *
 | 
						||
     * @param  string  $openid  接收者openid
 | 
						||
     * @param  array  $msgData  消息体 样例:['date1'=>date('Y年m月d日'), 'thing2'=>'植发', 'character_string12'=>'8:30 ~ 9:30']
 | 
						||
     * @param  string  $state  跳转小程序类型。 developer为开发版;trial为体验版;formal为正式版;默认为正式版
 | 
						||
     * @return array ['status'=>[false|true], 'msgid'=>'']
 | 
						||
     */
 | 
						||
    public function sendAppointmentSubscribeMessage(string $openid, array $msgData, string $state = 'formal'): array
 | 
						||
    {
 | 
						||
        $resp = ['status' => false, 'msgid' => ''];
 | 
						||
        // 跳转到预约列表界面
 | 
						||
        $page = Config::MINI_PATH_APPOINTMENT;
 | 
						||
 | 
						||
        try {
 | 
						||
            if (empty($openid) || empty($msgData)) {
 | 
						||
                return $resp;
 | 
						||
            }
 | 
						||
 | 
						||
            $wxApp    = WechatApplets::getInstance();
 | 
						||
            $dataList = [];
 | 
						||
            foreach ($msgData as $tk => $tv) {
 | 
						||
                $dataList[$tk]['value'] = $tv;
 | 
						||
            }
 | 
						||
 | 
						||
            $templateId = WechatApplets::SUBSCRIBE_TPL_APPOINTMENT;
 | 
						||
            $data       = [
 | 
						||
                // 所需下发的订阅模板id
 | 
						||
                'template_id'       => $templateId,
 | 
						||
                // 接收者(用户)的 openid
 | 
						||
                'touser'            => $openid,
 | 
						||
                // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
 | 
						||
                'page'              => $page,
 | 
						||
                //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
 | 
						||
                'miniprogram_state' => $state,
 | 
						||
                // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
 | 
						||
                'data'              => $dataList,
 | 
						||
 | 
						||
            ];
 | 
						||
 | 
						||
            $res = $wxApp->subscribe_message->send($data);
 | 
						||
            if (isset($res['errcode']) && $res['errcode'] == 0) {
 | 
						||
                $resp = ['status' => true, 'msgid' => $res['msgid'] ?? ''];
 | 
						||
            }
 | 
						||
        } catch (GuzzleException | Exception $e) {
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        return $resp;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 订阅消息发送
 | 
						||
     *
 | 
						||
     * @param  int  $messageId
 | 
						||
     * @param  string  $templateId
 | 
						||
     * @param  array  $targetList
 | 
						||
     * @param  array  $messageData
 | 
						||
     * @param  string  $page
 | 
						||
     * @param  string  $state
 | 
						||
     * @throws GuzzleException
 | 
						||
     * @throws RepositoryException
 | 
						||
     */
 | 
						||
    public function subscribeSend(int $messageId, string $templateId, array $targetList = [], array $messageData = [], string $page = '', string $state = '')
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            $accountModel = new Account();
 | 
						||
            if (!empty($targetList)) {
 | 
						||
                $accountModel = $accountModel->whereIn('id', $targetList);
 | 
						||
            }
 | 
						||
 | 
						||
            $accountList = $accountModel->field('openid, id, nickname')->select();
 | 
						||
 | 
						||
            // ['template_id' => '模版ID', 'msg' => msgBody, 'page' => '小程序跳转页面', 'state' => '小程序类型']
 | 
						||
            $data = [
 | 
						||
                'template_id' => $templateId,
 | 
						||
                'msg'         => $messageData,
 | 
						||
                'page'        => $page
 | 
						||
            ];
 | 
						||
 | 
						||
            if (!empty($state)) {
 | 
						||
                $data['state'] = $state;
 | 
						||
            }
 | 
						||
 | 
						||
            WechatApplets::sendBatchSubscribeMessage($messageId, $accountList->column('openid'), $data);
 | 
						||
        } catch (RepositoryException | Exception $e) {
 | 
						||
            throw $e;
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 短信发送
 | 
						||
     *
 | 
						||
     * @param  int  $messageId
 | 
						||
     * @param  string  $templateId
 | 
						||
     * @param  array  $targetList
 | 
						||
     * @param  array  $messageData
 | 
						||
     * @throws GuzzleException
 | 
						||
     * @throws RepositoryException
 | 
						||
     */
 | 
						||
    public function smsSendBak(int $messageId, string $templateId, array $targetList = [], array $messageData = [])
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            //            var_dump($messageData);
 | 
						||
            //            exit;
 | 
						||
            $accountModel = new Account();
 | 
						||
            if (!empty($targetList)) {
 | 
						||
                $accountModel = $accountModel->whereIn('id', $targetList);
 | 
						||
            }
 | 
						||
 | 
						||
            $accountList = $accountModel->field('mobile, id, nickname')->select();
 | 
						||
 | 
						||
            // ['template_id' => '模版ID', 'msg' => msgBody]
 | 
						||
            $data = [
 | 
						||
                'phoneNumberJson'   => '', // 如'["13541194xxxx"]'
 | 
						||
                'signNameJson'      => '',// 如 '["商城","商城"]'
 | 
						||
                'templateCode'      => '',
 | 
						||
                'templateParamJson' => '', //如 '[{"code":"12345"},{"code":"333"}]'
 | 
						||
            ];
 | 
						||
 | 
						||
            if ($accountList->count() <= 1000) {
 | 
						||
                $templateParamArr = [];
 | 
						||
                $signNameArr      = [];
 | 
						||
                $mobileArr        = [];
 | 
						||
                foreach ($accountModel->column('mobile') as $mobile) {
 | 
						||
                    if (!empty($mobile)) {
 | 
						||
                        array_push($mobileArr, $mobile);
 | 
						||
                        array_push($signNameArr, Sms::SMS_SIGN);
 | 
						||
                        if (!empty($messageData)) {
 | 
						||
                            array_push($templateParamArr, $messageData);
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                }
 | 
						||
 | 
						||
                $data['phoneNumberJson']   = json_encode($mobileArr, JSON_UNESCAPED_UNICODE);
 | 
						||
                $data['signNameJson']      = json_encode($signNameArr, JSON_UNESCAPED_UNICODE);
 | 
						||
                $data['templateCode']      = $templateId;
 | 
						||
                $data['templateParamJson'] = json_encode($templateParamArr, JSON_UNESCAPED_UNICODE);
 | 
						||
 | 
						||
                Log::error('[短信批量发送日志]'.json_encode($data, JSON_UNESCAPED_UNICODE));
 | 
						||
                Sms::batchSendByApi($data);
 | 
						||
            } else {
 | 
						||
                Sms::batchSendByApi($data);
 | 
						||
            }
 | 
						||
        } catch (RepositoryException | Exception $e) {
 | 
						||
            throw $e;
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 短信发送[支持批量]
 | 
						||
     *
 | 
						||
     * @param  int  $messageId
 | 
						||
     * @param  string  $templateId
 | 
						||
     * @param  array  $targetList 用户ID列表
 | 
						||
     * @param  array  $messageData
 | 
						||
     * @throws Exception
 | 
						||
     * @return  array
 | 
						||
     */
 | 
						||
    public function smsSend(int $messageId, string $templateId, array $targetList = [], array $messageData = []): array
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            $accountModel = new Account();
 | 
						||
            if (!empty($targetList)) {
 | 
						||
                $accountModel = $accountModel->whereIn('id', $targetList);
 | 
						||
            }
 | 
						||
 | 
						||
            $accountList = $accountModel->whereNotNull('mobile')->field('mobile, id, nickname')->select();
 | 
						||
 | 
						||
            Log::error('[短信批量发送日志]'.json_encode($messageData, JSON_UNESCAPED_UNICODE));
 | 
						||
 | 
						||
            $smsLog     = [];
 | 
						||
            $now        = date('Y-m-d H:i:s');
 | 
						||
            $successNum = 0;
 | 
						||
            $failNum    = 0;
 | 
						||
            $total      = $accountList->count();
 | 
						||
            foreach ($accountList->column('mobile') as $mobile) {
 | 
						||
                if (empty($mobile)) {
 | 
						||
                    continue;
 | 
						||
                }
 | 
						||
 | 
						||
                $arr               = [];
 | 
						||
                $arr['phone']      = $mobile;
 | 
						||
                $arr['type']       = $templateId;
 | 
						||
                $arr['created_at'] = $now;
 | 
						||
                $arr['data']       = !empty($messageData) ? json_encode($messageData, JSON_UNESCAPED_UNICODE) : '';
 | 
						||
                $arr['message_id'] = $messageId;
 | 
						||
                $arr['status']     = Sms::STATUS_SUCCESS;
 | 
						||
 | 
						||
                $res = Sms::send($mobile, $messageData, $templateId);
 | 
						||
 | 
						||
                $success = true;
 | 
						||
                if ($res !== true) {
 | 
						||
                    $arr['status']  = Sms::STATUS_FAIL;
 | 
						||
                    $arr['remarks'] = $res;
 | 
						||
                    $success        = false;
 | 
						||
                }
 | 
						||
 | 
						||
                if ($success) {
 | 
						||
                    $successNum++;
 | 
						||
                } else {
 | 
						||
                    $failNum++;
 | 
						||
                }
 | 
						||
 | 
						||
                $smsLog[] = $arr;
 | 
						||
            }
 | 
						||
 | 
						||
            if (!empty($smsLog)) {
 | 
						||
                (new SmsLog())->insertAll($smsLog);
 | 
						||
            }
 | 
						||
 | 
						||
            return [
 | 
						||
                'status' => $total == $successNum,
 | 
						||
                'msg'    => sprintf("总数%d条,发送成功%d条,发送失败%d条", $total, $successNum, $failNum)
 | 
						||
            ];
 | 
						||
        } catch (Exception $e) {
 | 
						||
            return [
 | 
						||
                'status' => false,
 | 
						||
                'msg'    => $e->getMessage()
 | 
						||
            ];
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
} |