vip会员支持补差升级
This commit is contained in:
@@ -35,8 +35,26 @@ class VipPaymentService
|
||||
*/
|
||||
public function createLocalOrder(User $user, VipLevel $vipLevel): VipPaymentOrder
|
||||
{
|
||||
if ((float) $vipLevel->price <= 0) {
|
||||
throw new RuntimeException('当前 VIP 等级未设置在线支付价格,暂不支持直接购买。');
|
||||
$currentVip = $user->isVip() ? $user->vipLevel : null;
|
||||
$isUpgrade = $currentVip && $vipLevel->isHigherThan($currentVip);
|
||||
|
||||
// 如果已经是该等级或更高级别,且不是永久会员续费(逻辑上续费应该用原价,但此处 user 需求是升级补差价)
|
||||
// 这里我们主要处理补差价升级逻辑。
|
||||
$price = $isUpgrade
|
||||
? $vipLevel->getUpgradePrice($currentVip)
|
||||
: (float) $vipLevel->price;
|
||||
|
||||
if ($price < 0.01) {
|
||||
// 如果差价极小或为 0(例如同级或降级),抛出异常或根据业务逻辑处理
|
||||
if ($isUpgrade) {
|
||||
throw new RuntimeException('当前等级差价不足 0.01 元,无法发起升级。');
|
||||
}
|
||||
if ($user->vip_level_id === $vipLevel->id) {
|
||||
// 续费逻辑保持原价
|
||||
$price = (float) $vipLevel->price;
|
||||
} else {
|
||||
throw new RuntimeException('不支持降级购买会员。');
|
||||
}
|
||||
}
|
||||
|
||||
return VipPaymentOrder::create([
|
||||
@@ -45,13 +63,15 @@ class VipPaymentService
|
||||
'user_id' => $user->id,
|
||||
'vip_level_id' => $vipLevel->id,
|
||||
'status' => 'created',
|
||||
'amount' => $vipLevel->price,
|
||||
'subject' => '购买 VIP 会员 - '.$vipLevel->name,
|
||||
'amount' => $price,
|
||||
'subject' => ($isUpgrade ? '【升级】' : '购买') . ' VIP 会员 - ' . $vipLevel->name,
|
||||
'provider' => 'alipay',
|
||||
'vip_name' => $vipLevel->name,
|
||||
'vip_duration_days' => (int) $vipLevel->duration_days,
|
||||
'meta' => [
|
||||
'username' => $user->username,
|
||||
'is_upgrade' => $isUpgrade,
|
||||
'old_vip_level_id' => $currentVip?->id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
@@ -188,7 +208,11 @@ class VipPaymentService
|
||||
if (! $lockedOrder->isVipOpened()) {
|
||||
// 只在首次成功支付时开通会员,防止重复回调导致会员时长重复叠加。
|
||||
$user = User::query()->lockForUpdate()->findOrFail($lockedOrder->user_id);
|
||||
$this->vipService->grantVip($user, $lockedOrder->vip_level_id, (int) $lockedOrder->vip_duration_days);
|
||||
|
||||
// 从 meta 中提取是否是升级
|
||||
$isUpgrade = (bool) ($lockedOrder->meta['is_upgrade'] ?? false);
|
||||
|
||||
$this->vipService->grantVip($user, $lockedOrder->vip_level_id, (int) $lockedOrder->vip_duration_days, $isUpgrade);
|
||||
|
||||
$lockedOrder->update([
|
||||
'opened_vip_at' => now(),
|
||||
|
||||
Reference in New Issue
Block a user