feat : auto dispense coupon
This commit is contained in:
@@ -39,7 +39,7 @@ class CouponAutoDispenseConsumer extends ConsumerMessage
|
||||
*/
|
||||
public function consumeMessage($data, AMQPMessage $message): Result
|
||||
{
|
||||
if (!$data['coupon_dispense_id']) {
|
||||
if (!$data['coupon_dispense_id'] || !$data['user_id']) {
|
||||
$this->log->error('CouponAutoDispenseConsumer:error:NoData:'.json_encode($data));
|
||||
return Result::ACK;
|
||||
}
|
||||
@@ -48,6 +48,7 @@ class CouponAutoDispenseConsumer extends ConsumerMessage
|
||||
$service = new AutoDispenseService();
|
||||
|
||||
$service->couponDispenseId = $data['coupon_dispense_id'];
|
||||
$service->userId = $data['user_id'];
|
||||
|
||||
$service->handle();
|
||||
|
||||
|
||||
73
app/Amqp/Consumer/WxSubMessageConsumer.php
Normal file
73
app/Amqp/Consumer/WxSubMessageConsumer.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Amqp\Consumer;
|
||||
|
||||
use App\Constants\Common\ThirdCode;
|
||||
use App\Constants\Common\WxMiniCode;
|
||||
use App\Exception\ErrException;
|
||||
use App\Lib\Log;
|
||||
use App\Model\UserThird;
|
||||
use App\Service\ServiceTrait\Api\WxMiniTrait;
|
||||
use Exception;
|
||||
use Hyperf\Amqp\Message\Type;
|
||||
use Hyperf\Amqp\Result;
|
||||
use Hyperf\Amqp\Annotation\Consumer;
|
||||
use Hyperf\Amqp\Message\ConsumerMessage;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
#[Consumer(exchange: 'wxSubMessage', routingKey: 'wxSubMessage', queue: 'wxSubMessage.send', name: "WxSubMessageConsumer", nums: 1)]
|
||||
class WxSubMessageConsumer extends ConsumerMessage
|
||||
{
|
||||
use WxMiniTrait;
|
||||
|
||||
/**
|
||||
* @var Type|string 消息类型
|
||||
*/
|
||||
protected Type|string $type = Type::DIRECT;
|
||||
|
||||
/**
|
||||
* @var Log
|
||||
*/
|
||||
#[Inject]
|
||||
protected Log $log;
|
||||
|
||||
/**
|
||||
* @var UserThird
|
||||
*/
|
||||
#[Inject]
|
||||
protected UserThird $userThirdModel;
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param AMQPMessage $message
|
||||
* @return Result
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function consumeMessage($data, AMQPMessage $message): Result
|
||||
{
|
||||
if (!$data['type'] || !$data['user_id'] || !$data['data']) {
|
||||
$this->log->error('WxSubMessageConsumer:error:NoData:'.json_encode($data));
|
||||
return Result::ACK;
|
||||
}
|
||||
|
||||
$openId = $this->userThirdModel->where('user_id',$data['user_id'])->where('type',ThirdCode::WX_LOGIN)->value('open_id') ?? null;
|
||||
if (empty($openId)) {
|
||||
$this->log->error('WxSubMessageConsumer:error:NoOpenId:'.json_encode($data));
|
||||
return Result::ACK;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->sendSubMessage(WxMiniCode::TEMPLATE_ID_LIST[$data['type']],$openId,$data['data'],$data['page'] ?? null);
|
||||
} catch (Exception|ErrException $e) {
|
||||
$this->log->error('WxSubMessageConsumer:error:'.$e->getMessage().':data:'.json_encode($data));
|
||||
}
|
||||
|
||||
return Result::ACK;
|
||||
}
|
||||
}
|
||||
26
app/Amqp/Producer/WxSubMessageProducer.php
Normal file
26
app/Amqp/Producer/WxSubMessageProducer.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Amqp\Producer;
|
||||
|
||||
use Hyperf\Amqp\Annotation\Producer;
|
||||
use Hyperf\Amqp\Message\ProducerMessage;
|
||||
use Hyperf\Amqp\Message\Type;
|
||||
|
||||
#[Producer(exchange: 'wxSubMessage', routingKey: 'wxSubMessage')]
|
||||
class WxSubMessageProducer extends ProducerMessage
|
||||
{
|
||||
/**
|
||||
* @var Type|string 消息类型
|
||||
*/
|
||||
protected Type|string $type = Type::DIRECT;
|
||||
|
||||
public function __construct($data)
|
||||
{
|
||||
/**
|
||||
* $data string array => {"type":"1","user_id":"1","data":[],"page":null}
|
||||
*/
|
||||
$this->payload = $data;
|
||||
}
|
||||
}
|
||||
24
app/Constants/Common/WxMiniCode.php
Normal file
24
app/Constants/Common/WxMiniCode.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Constants\Common;
|
||||
|
||||
class WxMiniCode
|
||||
{
|
||||
/**
|
||||
* 发送优惠券订阅消息模板id
|
||||
*/
|
||||
const string SEND_SUB_MESSAGE_GET_COUPON_TEMPLATE_ID = 'akV-wJt0AHWBpzPKvIsa0IRuzrf5yWPaMYvRRioI8XM';
|
||||
const string SEND_SUB_MESSAGE_DELIVER_TEMPLATE_ID = 'xxxxxxxxxx';
|
||||
|
||||
/**
|
||||
* @var int 发送消息类型 1=获取优惠券 2=送达
|
||||
*/
|
||||
CONST INT SEND_MSG_TYPE_GET_COUPON = 1;
|
||||
CONST INT SEND_MSG_TYPE_DELIVER = 2;
|
||||
|
||||
const array TEMPLATE_ID_LIST = [
|
||||
self::SEND_MSG_TYPE_GET_COUPON => self::SEND_SUB_MESSAGE_GET_COUPON_TEMPLATE_ID,
|
||||
self::SEND_MSG_TYPE_DELIVER => self::SEND_SUB_MESSAGE_DELIVER_TEMPLATE_ID
|
||||
];
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Model;
|
||||
|
||||
use App\Constants\Common\CouponCode;
|
||||
use Hyperf\Database\Model\Builder;
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
|
||||
/**
|
||||
@@ -58,6 +59,16 @@ class CouponDispenseUser extends Model
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dispenseId
|
||||
* @param int $userId
|
||||
* @return Builder|\Hyperf\Database\Model\Model|null
|
||||
*/
|
||||
public function getInfoByDispenseIdAndUserId(int $dispenseId, int $userId): \Hyperf\Database\Model\Model|Builder|null
|
||||
{
|
||||
return $this->where('dispense_id', $dispenseId)->where('user_id', $userId)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $userIds
|
||||
* @param int $count
|
||||
|
||||
@@ -71,6 +71,12 @@ class DispenseAddService extends BaseService
|
||||
#[Inject]
|
||||
protected CouponTemplate $couponTemplateModel;
|
||||
|
||||
/**
|
||||
* @var Producer
|
||||
*/
|
||||
#[Inject]
|
||||
protected Producer $producer;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@@ -132,14 +138,7 @@ class DispenseAddService extends BaseService
|
||||
$this->addSubTableInformation($this->dispenseId);
|
||||
});
|
||||
|
||||
if ($this->claimRule == CouponCode::DISPENSE_CLAIM_RULE_POST_ACCOUNT) {
|
||||
//mq发放优惠券
|
||||
$message = new CouponAutoDispenseProducer([
|
||||
'coupon_dispense_id' => $this->dispenseId,
|
||||
]);
|
||||
$producer = ApplicationContext::getContainer()->get(Producer::class);
|
||||
$producer->produce($message);
|
||||
}
|
||||
$this->sendAutoMq();
|
||||
|
||||
return $this->return->success();
|
||||
}catch (Exception $e) {
|
||||
@@ -147,6 +146,28 @@ class DispenseAddService extends BaseService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function sendAutoMq(): void
|
||||
{
|
||||
if ($this->claimRule != CouponCode::DISPENSE_CLAIM_RULE_POST_ACCOUNT) return;
|
||||
|
||||
if (empty($this->userIds)) return;
|
||||
|
||||
foreach ($this->userIds as $userId) {
|
||||
//mq发放优惠券
|
||||
$message = new CouponAutoDispenseProducer([
|
||||
'coupon_dispense_id' => $this->dispenseId,
|
||||
'user_id' => $userId,
|
||||
]);
|
||||
// $producer = ApplicationContext::getContainer()->get(Producer::class);
|
||||
$this->producer->produce($message);
|
||||
}
|
||||
|
||||
//todo 加一个缓存进度控制器 有没有必要
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dispenseId
|
||||
* @return void
|
||||
|
||||
@@ -10,19 +10,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Amqp\Coupon;
|
||||
|
||||
use App\Amqp\Producer\WxSubMessageProducer;
|
||||
use App\Constants\Common\CouponCode;
|
||||
use App\Constants\Common\WxMiniCode;
|
||||
use App\Model\CouponDispenseLog;
|
||||
use App\Model\CouponDispenseUser;
|
||||
use App\Model\CouponTemplate;
|
||||
use App\Model\UserCoupon;
|
||||
use App\Service\ServiceTrait\Api\CouponTrait;
|
||||
use Exception;
|
||||
use Hyperf\Coroutine\Coroutine;
|
||||
use Hyperf\Amqp\Producer;
|
||||
use Hyperf\DbConnection\Db;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
class AutoDispenseService
|
||||
{
|
||||
|
||||
const int SINGLE_MAX = 1;
|
||||
use CouponTrait;
|
||||
|
||||
/**
|
||||
* @var CouponDispenseLog
|
||||
@@ -36,59 +39,108 @@ class AutoDispenseService
|
||||
#[Inject]
|
||||
protected CouponDispenseUser $couponDispenseUserModel;
|
||||
|
||||
/**
|
||||
* @var UserCoupon
|
||||
*/
|
||||
#[Inject]
|
||||
protected UserCoupon $userCouponModel;
|
||||
|
||||
/**
|
||||
* @var CouponTemplate
|
||||
*/
|
||||
#[Inject]
|
||||
protected CouponTemplate $couponTemplateModel;
|
||||
|
||||
/**
|
||||
* @var Producer
|
||||
*/
|
||||
#[Inject]
|
||||
protected Producer $producer;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public int $couponDispenseId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public int $userId;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$dispenseInfo = $this->couponDispenseLogModel->getInfoById($this->couponDispenseId);
|
||||
|
||||
if (empty($dispenseInfo)) throw new Exception('分发记录不存在');
|
||||
|
||||
$userIds = $this->couponDispenseUserModel->getNoSendUserListByDispenseId($this->couponDispenseId);
|
||||
if (empty($userIds)) throw new Exception('该分发已发送完毕');
|
||||
$templateInfo = $this->couponTemplateModel->getInfoById($dispenseInfo->coupon_template_id);
|
||||
if (empty($templateInfo)) throw new Exception('优惠券模板不存在');
|
||||
|
||||
$partArr = array_chunk($userIds, self::SINGLE_MAX);
|
||||
$validityTime = $this->getValidityTime((int)$dispenseInfo->validity_time_type, $dispenseInfo->validity_time_value);
|
||||
//有效期不存在或者到期销毁当前分发逻辑
|
||||
if (empty($validityTime) || empty($validityTime['start_time']) || empty($validityTime['end_time']) || $validityTime['end_time'] < date('Y-m-d H:i:s')) {
|
||||
$dispenseInfo->status = CouponCode::DISPENSE_NULL;
|
||||
if (!$dispenseInfo->save()) throw new Exception('修改分发记录状态失败');
|
||||
throw new Exception('该分发逻辑已失效');
|
||||
}
|
||||
|
||||
foreach ($partArr as $onePart) {
|
||||
$insertData = [];
|
||||
foreach ($onePart as $oneUser) {
|
||||
// 模拟数据
|
||||
$oneUserData = [
|
||||
'user_id' => $oneUser,
|
||||
'coupon_template_id' => $dispenseInfo->coupon_template_id,
|
||||
'coupon_name' => $dispenseInfo->coupon_name,
|
||||
'coupon_dispense_id' => $dispenseInfo->id,
|
||||
'status' => CouponCode::COUPON_STATUS_UNUSED,
|
||||
'validity_start_time' => $dispenseInfo->validity_start_time,
|
||||
'validity_end_time' => $dispenseInfo->validity_end_time,
|
||||
];
|
||||
$userDispenseInfo = $this->couponDispenseUserModel->getInfoByDispenseIdAndUserId($this->couponDispenseId,$this->userId);
|
||||
if (empty($userDispenseInfo)) throw new Exception('该用户不属于该分发逻辑');
|
||||
|
||||
$copies = array_map(function () use ($oneUserData) {
|
||||
return $oneUserData;
|
||||
}, array_fill(0, $dispenseInfo->item_count, null));
|
||||
$userCount = $this->userCouponModel->where('coupon_dispense_id',$this->couponDispenseId)->where('user_id',$this->userId)->count() ?? 0;
|
||||
if ($userCount >= $dispenseInfo->item_count) throw new Exception('该用户该分发逻辑已分发完毕');
|
||||
|
||||
$insertData = array_merge($insertData, $copies);
|
||||
}
|
||||
// 数据
|
||||
$oneData = [
|
||||
'user_id' => $this->userId,
|
||||
'coupon_template_id' => $dispenseInfo->coupon_template_id,
|
||||
'coupon_name' => $dispenseInfo->coupon_name,
|
||||
'coupon_dispense_id' => $dispenseInfo->id,
|
||||
'status' => CouponCode::COUPON_STATUS_UNUSED,
|
||||
'validity_start_time' => $validityTime['start_time'],
|
||||
'validity_end_time' => $validityTime['end_time'],
|
||||
];
|
||||
|
||||
Db::transaction(function () use ($insertData,$dispenseInfo,$onePart) {
|
||||
//添加优惠券信息
|
||||
if (!(new UserCoupon())->insert($insertData)) throw new Exception('写入数据失败');
|
||||
//修改分发用户信息
|
||||
if (!(new CouponDispenseUser())->updateReceiveCountByUserIds($onePart,$dispenseInfo->item_count)) throw new Exception('修改分发用户信息失败');
|
||||
$insertData = array_map(function () use ($oneData) {
|
||||
return $oneData;
|
||||
}, array_fill(0, $dispenseInfo->item_count - $userCount, null));
|
||||
|
||||
//修改分发 log 信息 (修改receive_count = origin_value + count($insertData) ps : 查询还没发的用户 * item_count / total_count = 完成百分比)
|
||||
if (!(new CouponDispenseLog())->updateReceiveCountById($dispenseInfo->id,count($insertData))) throw new Exception('修改分发log信息失败');
|
||||
});
|
||||
Db::transaction(function () use ($insertData,$dispenseInfo,$userDispenseInfo) {
|
||||
// 添加优惠券信息
|
||||
if (!(new UserCoupon())->insert($insertData)) throw new Exception('写入数据失败');
|
||||
|
||||
// 休息1秒
|
||||
Coroutine::sleep(1);
|
||||
// 修改分发用户信息
|
||||
$userDispenseInfo->receive_count = $userDispenseInfo->receive_count + count($insertData);
|
||||
$userDispenseInfo->is_receive = CouponCode::DISPENSE_STATUS_IS_RECEIVED;
|
||||
if (!$userDispenseInfo->save()) throw new Exception('修改分发用户信息失败');
|
||||
|
||||
//修改分发 log 信息 (修改receive_count = origin_value + count($insertData) ps : 查询还没发的用户 * item_count / total_count = 完成百分比)
|
||||
$dispenseInfo->receive_count = $dispenseInfo->receive_count + count($insertData);
|
||||
if (!$dispenseInfo->save()) throw new Exception('修改分发log信息失败');
|
||||
});
|
||||
|
||||
$nominalValue = match ($templateInfo->coupon_type) {
|
||||
CouponCode::COUPON_TYPE_INSTANT_REDUCTION => $templateInfo->amount.'元',
|
||||
CouponCode::COUPON_TYPE_DISCOUNT => ($templateInfo->ratio * 10).'%',
|
||||
};
|
||||
|
||||
foreach ($insertData as $item) {
|
||||
$msgData = [
|
||||
'thing2' => ['value' => $dispenseInfo->coupon_name],
|
||||
'thing9' => ['value' => $nominalValue],
|
||||
'thing8' => ['value' => $validityTime['start_time'].'/'.$validityTime['end_time']],
|
||||
'thing4' => ['value' => 'xxx'],
|
||||
];
|
||||
|
||||
$message = new WxSubMessageProducer([
|
||||
'type' => WxMiniCode::SEND_MSG_TYPE_GET_COUPON,
|
||||
'user_id' => $this->userId,
|
||||
'data' => $msgData,
|
||||
'page' => null
|
||||
]);
|
||||
$this->producer->produce($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,14 @@ use App\Extend\DateUtil;
|
||||
use App\Model\CouponDispenseLog;
|
||||
use App\Model\UserCoupon;
|
||||
use App\Service\Api\BaseService;
|
||||
use App\Service\ServiceTrait\Api\CouponTrait;
|
||||
use Hyperf\DbConnection\Db;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
class ReceiveService extends BaseService
|
||||
{
|
||||
use CouponTrait;
|
||||
|
||||
/**
|
||||
* @var CouponDispenseLog
|
||||
*/
|
||||
@@ -71,22 +74,10 @@ class ReceiveService extends BaseService
|
||||
if (empty($couponArr)) return;
|
||||
|
||||
foreach ($couponArr as $item) {
|
||||
$validityTime = [];
|
||||
switch ($item['validity_time_type']) {
|
||||
case CouponCode::VALIDITY_TIME_TYPE_CYCLE:
|
||||
$validityValue = json_decode($item['validity_time_value'],true);
|
||||
$validityTime = [
|
||||
'start_time' => date('Y-m-d H:i:s'),
|
||||
'end_time' => date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY))
|
||||
];
|
||||
break;
|
||||
case CouponCode::VALIDITY_TIME_TYPE_FIX:
|
||||
$validityTime = json_decode($item['validity_time_value'],true);
|
||||
break;
|
||||
}
|
||||
$validityTime = $this->getValidityTime((int)$item['validity_time_type'], $item['validity_time_value']);
|
||||
|
||||
//有效期不存在或者到期销毁当前分发逻辑
|
||||
if (($validityTime['end_time'] ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
|
||||
if (empty($validityTime) || ($validityTime['end_time'] ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
|
||||
$this->destroyDispenseData[] = $item['id'];
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Service\ServiceTrait\Api;
|
||||
|
||||
use App\Constants\Common\CouponCode;
|
||||
use App\Constants\Common\OrderCode;
|
||||
use App\Extend\DateUtil;
|
||||
use App\Model\UserCoupon;
|
||||
use Exception;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
@@ -38,4 +39,25 @@ trait CouponTrait
|
||||
|
||||
if (!$couponInfo->save()) throw new Exception('CancelOrderConsumer:error:couponStatusUpdateError:'.json_encode($orderInfo->toArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
* @param string $value
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidityTime(int $type,string $value): array
|
||||
{
|
||||
switch ($type) {
|
||||
case CouponCode::VALIDITY_TIME_TYPE_CYCLE:
|
||||
$validityValue = json_decode($value,true);
|
||||
return [
|
||||
'start_time' => date('Y-m-d H:i:s'),
|
||||
'end_time' => date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY))
|
||||
];
|
||||
case CouponCode::VALIDITY_TIME_TYPE_FIX:
|
||||
return json_decode($value,true);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use App\Cache\Redis\Common\CommonRedisKey;
|
||||
use App\Cache\Redis\RedisCache;
|
||||
use App\Constants\RedisCode;
|
||||
use App\Exception\ErrException;
|
||||
use App\Extend\SystemUtil;
|
||||
use App\Lib\Log;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
@@ -194,4 +195,54 @@ trait WxMiniTrait
|
||||
throw new ErrException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $templateId
|
||||
* @param string $toUserOpenId
|
||||
* @param array $data
|
||||
* @param string|null $page
|
||||
* @return mixed
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
protected function sendSubMessage(string $templateId, string $toUserOpenId, array $data ,string $page = null): mixed
|
||||
{
|
||||
$url = sprintf(
|
||||
'/cgi-bin/message/subscribe/send?access_token=%s',
|
||||
$this->getAccessTokenCache()
|
||||
);
|
||||
|
||||
$params = [
|
||||
'template_id' => $templateId,
|
||||
'touser' => $toUserOpenId,
|
||||
'data' => $data,
|
||||
'miniprogram_state' => !SystemUtil::checkProEnv() ? 'developer' : 'formal', //不是正式环境 使用开发版
|
||||
'lang' => 'zh_CN'
|
||||
];
|
||||
if (!empty($page)) $params['page'] = $page;
|
||||
|
||||
try {
|
||||
$wxResponse = $this->clientFactory->create([
|
||||
'base_uri' => $this->BaseUri,
|
||||
'timeout' => 5
|
||||
])->post($url,[
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json'
|
||||
],
|
||||
'body' => json_encode($params)
|
||||
]);
|
||||
|
||||
$contents = $wxResponse->getBody()->getContents();
|
||||
|
||||
$this->log->callbackLog(__class__.':微信服务器返回send_sub_message信息:'.json_encode($contents));
|
||||
|
||||
$res = json_decode($contents,true);
|
||||
|
||||
if (!empty($res['errcode']) && $res['errcode'] != 0) throw new ErrException($res['errmsg'] ?? '系统繁忙');
|
||||
|
||||
return $res;
|
||||
}catch (GuzzleException $e){
|
||||
throw new ErrException($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user