|
@@ -234,6 +234,10 @@ class RewardPointRepository extends Repository
|
|
|
$customerPoints->last_checkout = Carbon::now();
|
|
$customerPoints->last_checkout = Carbon::now();
|
|
|
$customerPoints->save();
|
|
$customerPoints->save();
|
|
|
|
|
|
|
|
|
|
+ // 按 FIFO(先过期先扣)扣减收入记录的 point_remaining,
|
|
|
|
|
+ // 避免这些积分到期时被 checkExpiredPoints 再次扣除
|
|
|
|
|
+ $this->deductFromEarningRecords($customerId, (int) $amount);
|
|
|
|
|
+
|
|
|
// 创建历史记录
|
|
// 创建历史记录
|
|
|
$history = $this->create([
|
|
$history = $this->create([
|
|
|
'customer_id' => $customerId,
|
|
'customer_id' => $customerId,
|
|
@@ -267,6 +271,49 @@ class RewardPointRepository extends Repository
|
|
|
throw $e;
|
|
throw $e;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按 FIFO(先过期先扣)顺序扣减收入记录的 point_remaining。
|
|
|
|
|
+ *
|
|
|
|
|
+ * 当用户消费积分时,需要同步扣减历史"获得积分"记录的剩余可过期积分,
|
|
|
|
|
+ * 否则这些积分到期时会被 checkExpiredPoints 再次扣除,导致重复扣分。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param int $customerId
|
|
|
|
|
+ * @param int $amount 需要扣减的积分总数(正数)
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function deductFromEarningRecords($customerId, int $amount): void
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($amount <= 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 只处理有剩余积分、有到期时间、未过期、状态为 COMPLETED 的"获得积分"记录
|
|
|
|
|
+ // 优先扣减先到期的记录(FIFO),符合用户利益
|
|
|
|
|
+ $earningRecords = $this->where('customer_id', $customerId)
|
|
|
|
|
+ ->where('amount', '>', 0)
|
|
|
|
|
+ ->whereNotNull('expired_time')
|
|
|
|
|
+ ->where('expired_time', '>', Carbon::now())
|
|
|
|
|
+ ->where('status', RewardPointHistory::STATUS_COMPLETED)
|
|
|
|
|
+ ->where('point_remaining', '>', 0)
|
|
|
|
|
+ ->orderByRaw('expired_time ASC, transaction_time ASC, history_id ASC')
|
|
|
|
|
+ ->lockForUpdate()
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $remaining = $amount;
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($earningRecords as $record) {
|
|
|
|
|
+ if ($remaining <= 0) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $deduct = min((int) $record->point_remaining, $remaining);
|
|
|
|
|
+
|
|
|
|
|
+ $record->point_remaining = (int) $record->point_remaining - $deduct;
|
|
|
|
|
+ $record->save();
|
|
|
|
|
+
|
|
|
|
|
+ $remaining -= $deduct;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function getHistory($customerId, $limit = 20, $page = null,$amountType = '')
|
|
public function getHistory($customerId, $limit = 20, $page = null,$amountType = '')
|
|
|
{
|
|
{
|
|
|
$query = $this->where('customer_id', $customerId)
|
|
$query = $this->where('customer_id', $customerId)
|