feat : coupon

This commit is contained in:
2025-03-04 17:42:49 +08:00
parent b49079fa58
commit 0d2932ea4a
4 changed files with 106 additions and 0 deletions

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace App\Model;
use App\Constants\Common\CouponCode;
use Hyperf\Collection\Collection;
use Hyperf\DbConnection\Model\Model;
/**
@@ -68,4 +70,32 @@ class CouponTemplate extends Model
return $res;
}
/**
* @param int $userId
* @return Collection
*/
public function getNoUseCouponByUserId(int $userId): Collection
{
return $this
->join('user_coupon', function ($join) use ($userId) {
$join->on('user_coupon.coupon_template_id', '=', 'coupon_template.id')
->where('user_coupon.user_id', '=', $userId)
->where('user_coupon.status', '=', CouponCode::COUPON_STATUS_UNUSED)
->where('validity_start_time', '<=', date('Y-m-d H:i:s'))
->where('validity_end_time', '>=', date('Y-m-d H:i:s'))
->select([
'coupon_template.coupon_type',
'coupon_template.amount',
'coupon_template.ratio',
'user_coupon.id',
'user_coupon.coupon_template_id',
'user_coupon.coupon_name',
'user_coupon.status',
'user_coupon.validity_start_time',
'user_coupon.validity_end_time',
]);
})
->get();
}
}

View File

@@ -4,6 +4,9 @@ declare(strict_types=1);
namespace App\Model;
use App\Constants\Common\CouponCode;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\DbConnection\Model\Model;
/**
@@ -48,4 +51,16 @@ class UserCoupon extends Model
->pluck('coupon_id')
->toArray();
}
/**
* @param int $userId
* @return Builder[]|Collection
*/
public function getNoUseCouponByUserId(int $userId): Collection|array
{
return $this
->where('user_id', $userId)
->where('status', CouponCode::COUPON_STATUS_UNUSED)
->get();
}
}

View File

@@ -12,6 +12,8 @@ namespace App\Service\Api\Order;
use App\Cache\Redis\Common\ConfigCache;
use App\Cache\Redis\RedisCache;
use App\Model\CouponTemplate;
use App\Model\UserCoupon;
use App\Service\Api\BaseService;
use App\Service\ServiceTrait\Api\OrderTrait;
use App\Service\ServiceTrait\Common\CycleTrait;
@@ -50,6 +52,18 @@ abstract class BaseOrderService extends BaseService
#[Inject]
protected ConfigCache $configCache;
/**
* @var UserCoupon
*/
#[Inject]
protected UserCoupon $userCouponModel;
/**
* @var CouponTemplate
*/
#[Inject]
protected CouponTemplate $couponTemplateModel;
/**
* @var array
*/

View File

@@ -10,6 +10,7 @@ declare(strict_types=1);
namespace App\Service\Api\Order;
use App\Constants\Common\CouponCode;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -36,6 +37,52 @@ class ConfirmationOrderService extends BaseOrderService
$this->compute();
$this->autoSelectCoupon();
return $this->return->success('success',$this->orderRes);
}
private function autoSelectCoupon(): void
{
if ($this->couponId != 0) return;
$noUseCoupon = $this->couponTemplateModel->getNoUseCouponByUserId($this->userId);
if ($noUseCoupon->isEmpty()) return;
$noUseCoupon = $noUseCoupon->toArray();
$orderMaxPrice = max(array_column($this->orderRes['good'],'price'));
$maxValidityEndTimeDate = max(array_column($noUseCoupon,'validity_end_time'));
$filtered = array_filter($noUseCoupon, function($item) use($maxValidityEndTimeDate) {
return $item['validity_end_time'] === $maxValidityEndTimeDate;
});
$selectMaxPrice = 0;
$selectCouponInfo = [];
foreach ($filtered as &$value) {
$value['amount'] = match ($value['coupon_type']) {
CouponCode::COUPON_TYPE_INSTANT_REDUCTION => $value['amount'],
CouponCode::COUPON_TYPE_DISCOUNT => $value['amount'] * $orderMaxPrice,
default => 0
};
if ($value['amount'] < $selectMaxPrice) continue;
$selectMaxPrice = $value['amount'];
$selectCouponInfo = $value;
}
$this->couponId = $selectCouponInfo['id'];
$this->orderRes['coupon'] = $selectCouponInfo;
$this->orderRes['coupon_id'] = $selectCouponInfo['id'];
$this->reloadCompute();
}
private function reloadCompute(): void
{
}
}