Files
hyperf_service/app/Service/Amqp/Order/GoodOrderFinishSuccessorService.php
2025-04-02 17:52:11 +08:00

267 lines
8.6 KiB
PHP

<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Amqp\Order;
use App\Amqp\Producer\WxSubMessageProducer;
use App\Cache\Redis\Common\ConfigCache;
use App\Constants\Common\AccountCode;
use App\Constants\Common\CouponCode;
use App\Constants\Common\OrderCode;
use App\Constants\Common\UserCode;
use App\Constants\Common\WxMiniCode;
use App\Constants\ConfigCode;
use App\Exception\ErrException;
use App\Model\CouponTemplate;
use App\Model\Order;
use App\Model\UserCoupon;
use App\Model\UserInvite;
use App\Service\Common\Account\PointOperateService;
use Exception;
use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class GoodOrderFinishSuccessorService
{
/**
* @var int
*/
public int $orderId;
/**
* @var Order
*/
#[Inject]
protected Order $orderModel;
/**
* @var Order
*/
protected Order $orderInfo;
/**
* @var ConfigCache
*/
#[Inject]
protected ConfigCache $configCache;
/**
* @var UserInvite
*/
#[Inject]
protected UserInvite $userInviteModel;
/**
* @var PointOperateService
*/
#[Inject]
protected PointOperateService $pointOperateService;
/**
* @var CouponTemplate
*/
#[Inject]
protected CouponTemplate $couponTemplateModel;
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function handle(): void
{
$this->orderInfo = $this->orderModel->find($this->orderId);
if (empty($this->orderInfo)) throw new Exception('订单不存在');
if ($this->orderInfo->status != OrderCode::FINISH) throw new Exception('订单状态错误');
try {
Db::beginTransaction();
$this->addOrderPoint();
$this->addInvite();
Db::commit();
}catch (Exception|ErrException $e) {
Db::rollBack();
throw new Exception($e->getMessage());
}
}
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function addOrderPoint(): void
{
$ratio = $this->configCache->getConfigValueByKey(ConfigCode::CONSUMPTION_RATIO);
if ($ratio <= 0) return;
$points = bcmul($this->orderInfo->actual_price,(string)$ratio,0);
$this->pointOperateService->inc(
$this->orderInfo->user_id,
$points,
AccountCode::GET_POINTS_FOR_COMPLETING_AN_ORDER,
['orderId' => $this->orderId]
);
}
/**
* @var UserInvite|null
*/
protected UserInvite|null $inviteInfo;
/**
* @var array
*/
protected array $couponTemplateList;
/**
* @var Producer
*/
#[Inject]
protected Producer $producer;
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function addInvite(): void
{
$this->inviteInfo = $this->userInviteModel->where('user_id',$this->orderInfo->user_id)->first();
if (empty($this->inviteInfo)) return;
if ($this->inviteInfo->status != UserCode::INVITE_STATUS_REGISTER) return;
$invitingCouponTemplateId = $this->configCache->getConfigValueByKey(ConfigCode::INVITING_PARTY_COUPON);
$invitingCouponValidity = $this->configCache->getConfigValueByKey(ConfigCode::INVITING_PARTY_COUPON_VALIDITY);
$inviteeCouponTemplateId = $this->configCache->getConfigValueByKey(ConfigCode::INVITED_PARTY_COUPON);
$inviteeCouponValidity = $this->configCache->getConfigValueByKey(ConfigCode::INVITEE_COUPON_VALIDITY);
$invitingCouponTemplateId = explode(',', $invitingCouponTemplateId);
$inviteeCouponTemplateId = explode(',', $inviteeCouponTemplateId);
$couponTemplateId = array_filter(array_merge($invitingCouponTemplateId,$inviteeCouponTemplateId));
if (empty($couponTemplateId)) return;
$this->couponTemplateList = $this->couponTemplateModel->getDataByIds($couponTemplateId);
if (empty($this->couponTemplateList)) return;
$invitingData = [];
$inviteeData = [];
// 随便一个为0代表不赠送
if ($invitingCouponTemplateId != 0 && $invitingCouponValidity != 0) $invitingData = $this->invitingAction($invitingCouponTemplateId,$invitingCouponValidity);
if ($inviteeCouponTemplateId != 0 && $inviteeCouponValidity != 0) $inviteeData = $this->inviteeAction($inviteeCouponTemplateId,$inviteeCouponValidity);
$insertData = array_merge($invitingData,$inviteeData);
if (empty($insertData)) return;
foreach ($insertData as $item) {
$nominalValue = match ($this->couponTemplateList[$item['coupon_template_id']]['coupon_type']) {
CouponCode::COUPON_TYPE_INSTANT_REDUCTION => $this->couponTemplateList[$item['coupon_template_id']]['amount'].'元',
CouponCode::COUPON_TYPE_DISCOUNT => ($this->couponTemplateList[$item['coupon_template_id']]['ratio'] * 10).'%',
};
$msgData = [
'thing2' => ['value' => $item['coupon_name']],
'thing9' => ['value' => $nominalValue],
'thing8' => ['value' => $item['validity_start_time'].'/'.$item['validity_end_time']],
'thing4' => ['value' => '您的优惠券已送达哦'],
];
$message = new WxSubMessageProducer([
'type' => WxMiniCode::SEND_MSG_TYPE_GET_COUPON,
'user_id' => $item['user_id'],
'data' => $msgData,
'page' => null
]);
$this->producer->produce($message);
}
}
/**
* @param array $invitingCouponTemplateId
* @param int $invitingCouponValidity
* @return array
* @throws Exception
*/
private function invitingAction(array $invitingCouponTemplateId,int $invitingCouponValidity): array
{
$insertCoupon = [];
foreach ($invitingCouponTemplateId as $one){
if ($this->couponTemplateList[$one]['status'] == CouponCode::COUPON_TEMPLATE_STATUS_ENABLE) continue;
$insertCoupon[] = [
'coupon_template_id' => $one,
'coupon_dispense_id' => CouponCode::SYSTEMIC_DISTRIBUTION,
'user_id' => $this->inviteInfo->invitee_user_id,
'status' => CouponCode::COUPON_STATUS_UNUSED,
'coupon_name' => $this->couponTemplateList[$one]['name'],
'validity_start_time' => date('Y-m-d H:i:s'),
'validity_end_time' => date('Y-m-d', strtotime('+'.$invitingCouponValidity.' days')),
];
}
if (empty($insertCoupon)) return [];
if (!(new UserCoupon)->insert($insertCoupon)) throw new Exception('赠送邀请优惠券失败:data:'.json_encode([
'invite' => $this->inviteInfo->toArray(),
'coupon_template_id' => $invitingCouponTemplateId,
'CouponValidity' => $invitingCouponValidity
]));
return $insertCoupon;
}
/**
* @param array $inviteeCouponTemplateId
* @param int $inviteeCouponValidity
* @return array
* @throws Exception
*/
private function inviteeAction(array $inviteeCouponTemplateId,int $inviteeCouponValidity): array
{
$insertCoupon = [];
foreach ($inviteeCouponTemplateId as $one){
if ($this->couponTemplateList[$one]['status'] == CouponCode::COUPON_TEMPLATE_STATUS_ENABLE) continue;
$insertCoupon[] = [
'coupon_template_id' => $one,
'coupon_dispense_id' => CouponCode::SYSTEMIC_DISTRIBUTION,
'user_id' => $this->inviteInfo->user_id,
'status' => CouponCode::COUPON_STATUS_UNUSED,
'coupon_name' => $this->couponTemplateList[$one]['name'],
'validity_start_time' => date('Y-m-d H:i:s'),
'validity_end_time' => date('Y-m-d', strtotime('+'.$inviteeCouponValidity.' days')),
];
}
if (empty($insertCoupon)) return [];
if (!(new UserCoupon)->insert($insertCoupon)) throw new Exception('赠送被邀请优惠券失败:data:'.json_encode([
'invite' => $this->inviteInfo->toArray(),
'coupon_template_id' => $inviteeCouponTemplateId,
'CouponValidity' => $inviteeCouponValidity
]));
return $insertCoupon;
}
}