新增每日签到与补签卡功能

This commit is contained in:
2026-04-24 22:47:27 +08:00
parent 34356a26ae
commit be9fc09d9d
46 changed files with 3934 additions and 55 deletions
+56 -4
View File
@@ -19,13 +19,19 @@ class ShopService
/**
* 购买商品入口:扣金币、按类型分发处理
*
* @return array{ok:bool, message:string, play_effect?:string}
* @return array{ok:bool, message:string, play_effect?:string, quantity?:int, total_price?:int}
*/
public function buyItem(User $user, ShopItem $item): array
public function buyItem(User $user, ShopItem $item, int $quantity = 1): array
{
if ($quantity !== 1 && $item->type !== ShopItem::TYPE_SIGN_REPAIR) {
return ['ok' => false, 'message' => '该商品暂不支持批量购买。'];
}
$totalPrice = $item->price * $quantity;
// 校验金币是否足够
if ($user->jjb < $item->price) {
return ['ok' => false, 'message' => "金币不足,购买 [{$item->name}] 需要 {$item->price} 金币,当前仅有 {$user->jjb} 金币。"];
if ($user->jjb < $totalPrice) {
return ['ok' => false, 'message' => "金币不足,购买 [{$item->name}] 需要 {$totalPrice} 金币,当前仅有 {$user->jjb} 金币。"];
}
return match ($item->type) {
@@ -34,6 +40,7 @@ class ShopService
'one_time' => $this->buyRenameCard($user, $item),
'ring' => $this->buyRing($user, $item),
'auto_fishing' => $this->buyAutoFishingCard($user, $item),
ShopItem::TYPE_SIGN_REPAIR => $this->buySignRepairCard($user, $item, $quantity),
default => ['ok' => false, 'message' => '未知商品类型'],
};
}
@@ -243,6 +250,39 @@ class ShopService
];
}
/**
* 购买签到补签卡:扣金币并写入可消耗背包记录。
*
* @return array{ok:bool, message:string, quantity:int, total_price:int}
*/
public function buySignRepairCard(User $user, ShopItem $item, int $quantity = 1): array
{
$quantity = max(1, min(99, $quantity));
$totalPrice = $item->price * $quantity;
DB::transaction(function () use ($user, $item, $quantity, $totalPrice): void {
// 补签卡支持一次购买多张,扣款必须按总价执行。
$user->decrement('jjb', $totalPrice);
for ($i = 0; $i < $quantity; $i++) {
// 每张补签卡保留独立购买记录,补签时逐张消耗。
UserPurchase::create([
'user_id' => $user->id,
'shop_item_id' => $item->id,
'status' => 'active',
'price_paid' => $item->price,
]);
}
});
return [
'ok' => true,
'message' => "🗓️ {$item->name} × {$quantity} 购买成功!可在签到日历中补签漏掉的日期。",
'quantity' => $quantity,
'total_price' => $totalPrice,
];
}
/**
* 获取用户当前激活的改名卡(是否持有未用改名卡)
*/
@@ -254,6 +294,18 @@ class ShopService
->exists();
}
/**
* 获取用户可用补签卡数量。
*/
public function getSignRepairCardCount(User $user): int
{
return UserPurchase::query()
->where('user_id', $user->id)
->where('status', 'active')
->whereHas('shopItem', fn ($q) => $q->where('type', ShopItem::TYPE_SIGN_REPAIR))
->count();
}
/**
* 购买自动钓鱼卡:手刺金币,写入 active 记录,到期时间 = 现在 + duration_minutes。
*