beginTransaction(); // Find all running orders for this user $stmt = $db->prepare("SELECT * FROM staking_records WHERE user_id = ? AND status = 'running' FOR UPDATE"); $stmt->execute([$userId]); $orders = $stmt->fetchAll(); $now = new DateTime(); foreach ($orders as $order) { $lastSettle = new DateTime($order['last_settle_time'] ?: $order['created_at']); $diff = $now->getTimestamp() - $lastSettle->getTimestamp(); if ($diff <= 0) continue; // Daily profit is a percentage (e.g. 0.02 is 2% daily) // But looking at the SQL dump: daily_profit was 0.02 for "ETH矿池" which had "8.2%" APY. // 8.2 / 365 = 0.02246... so 0.02 seems to be the daily percentage. $dailyRate = $order['daily_profit'] / 100; $profit = $order['amount'] * $dailyRate * ($diff / 86400); if ($profit > 0.00000001) { // Update balance $stmt = $db->prepare("UPDATE user_balances SET available = available + ? WHERE user_id = ? AND symbol = ?"); $stmt->execute([$profit, $userId, $order['symbol']]); // Add transaction record $stmt = $db->prepare("INSERT INTO transactions (user_id, symbol, type, amount, status) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$userId, $order['symbol'], 'mining_profit', $profit, 'completed']); // Update staking record $stmt = $db->prepare("UPDATE staking_records SET total_profit = total_profit + ?, last_settle_time = NOW() WHERE id = ?"); $stmt->execute([$profit, $order['id']]); // Check if it reached end_date $endDate = new DateTime($order['end_date']); if ($now >= $endDate) { $stmt = $db->prepare("UPDATE staking_records SET status = 'ended' WHERE id = ?"); $stmt->execute([$order['id']]); // Return principal $stmt = $db->prepare("UPDATE user_balances SET frozen = frozen - ?, available = available + ? WHERE user_id = ? AND symbol = ?"); $stmt->execute([$order['amount'], $order['amount'], $userId, $order['symbol']]); $stmt = $db->prepare("INSERT INTO transactions (user_id, symbol, type, amount, status) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$userId, $order['symbol'], 'mining_return', $order['amount'], 'completed']); } } } $db->commit(); } catch (Exception $e) { if ($db->inTransaction()) $db->rollBack(); error_log("Mining settlement failed for user $userId: " . $e->getMessage()); } }