make(QueuePoolDao::class); // 二次检查:防止重复退款 $record = $queueDao->get($queueId); if (!$record || (int)$record['status'] === 1) { Log::info("[QueueRefund] 记录 {$queueId} 已退款或不存在,跳过"); return true; } Db::transaction(function () use ($queueId, $uid, $amount, $batchNo, $queueDao) { // 1. 标记公排记录为已退款 $queueDao->markRefunded($queueId, $batchNo); // 2. 写入用户余额(使用 bcadd 避免浮点误差) /** @var UserDao $userDao */ $userDao = app()->make(UserDao::class); $user = $userDao->get($uid); if (!$user) { throw new \RuntimeException("用户 {$uid} 不存在"); } $newMoney = bcadd((string)$user['now_money'], (string)$amount, 2); $userDao->update($uid, ['now_money' => $newMoney], 'uid'); // 3. 写 user_bill 流水记录 /** @var UserBillDao $billDao */ $billDao = app()->make(UserBillDao::class); $billDao->save([ 'uid' => $uid, 'link_id' => $queueId, 'pm' => 1, 'title' => '公排退款', 'type' => 'queue_refund', 'category' => 'now_money', 'number' => $amount, 'balance' => $newMoney, 'mark' => "公排触发退款,批次#{$batchNo}", 'status' => 1, 'add_time' => time(), ]); }); Log::info("[QueueRefund] 退款成功 uid={$uid} amount={$amount} batch={$batchNo}"); } catch (\Throwable $e) { response_log_write([ 'message' => '公排退款失败: ' . $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ]); return false; } return true; } }