db = $db; } /** * 获取所有启用的跟单计划(前台展示) */ public function getActivePlans(int $gameId = 0): array { $where = ['status' => 1]; if ($gameId > 0) $where['game_id'] = $gameId; $where['ORDER'] = ['id' => 'ASC']; $plans = $this->db->select('follow_plans', '*', $where); foreach ($plans as &$plan) { $stats = $this->getPlanStats($plan['id']); $plan['total_records'] = $stats['total']; $plan['win_count'] = $stats['wins']; $plan['win_rate'] = $stats['total'] > 0 ? round($stats['wins'] / $stats['total'] * 100, 1) : 0; // 最近 10 期记录 $plan['recent'] = $this->db->select('follow_plan_records', '*', [ 'plan_id' => $plan['id'], 'is_win[!]' => null, 'ORDER' => ['id' => 'DESC'], 'LIMIT' => 10 ]); } unset($plan); return $plans; } /** * 获取计划统计 */ public function getPlanStats(int $planId): array { $total = $this->db->count('follow_plan_records', [ 'plan_id' => $planId, 'is_win[!]' => null ]); $wins = $this->db->count('follow_plan_records', [ 'plan_id' => $planId, 'is_win' => 1 ]); return ['total' => $total, 'wins' => $wins]; } /** * 获取用户的跟单状态 */ public function getUserFollowStatus(int $userId): array { $rows = $this->db->select('user_follow_plans', '*', [ 'user_id' => $userId, 'is_active' => 1 ]); $result = []; foreach ($rows as $r) { $result[$r['plan_id']] = $r; } return $result; } /** * 用户开始/停止跟单 */ public function toggleFollow(int $userId, int $planId): array { $existing = $this->db->get('user_follow_plans', '*', [ 'user_id' => $userId, 'plan_id' => $planId ]); if ($existing) { $newStatus = $existing['is_active'] ? 0 : 1; $this->db->update('user_follow_plans', ['is_active' => $newStatus], [ 'id' => $existing['id'] ]); return ['success' => true, 'active' => $newStatus]; } // 新建 $plan = $this->db->get('follow_plans', '*', ['id' => $planId, 'status' => 1]); if (!$plan) { return ['success' => false, 'message' => '计划不存在或已禁用']; } $this->db->insert('user_follow_plans', [ 'user_id' => $userId, 'plan_id' => $planId, 'is_active' => 1, ]); return ['success' => true, 'active' => 1]; } /** * 获取用户跟单汇总(总胜率、总盈亏) */ public function getUserSummary(int $userId): array { $pdo = $this->db->medoo->pdo; $totalWinRate = 0; $totalProfit = 0; try { $stmt = $pdo->prepare(" SELECT SUM(total_bets) as bets, SUM(total_wins) as wins, SUM(total_profit) as profit FROM user_follow_plans WHERE user_id = ? "); $stmt->execute([$userId]); $row = $stmt->fetch(\PDO::FETCH_ASSOC); $bets = intval($row['bets'] ?? 0); $wins = intval($row['wins'] ?? 0); $totalWinRate = $bets > 0 ? round($wins / $bets * 100, 1) : 0; $totalProfit = floatval($row['profit'] ?? 0); } catch (\Exception $e) {} return ['win_rate' => $totalWinRate, 'profit' => $totalProfit]; } // ===== 后台管理 ===== /** * 获取所有计划(后台) */ public function getAllPlans(): array { $plans = $this->db->select('follow_plans', '*', ['ORDER' => ['id' => 'DESC']]); foreach ($plans as &$plan) { $stats = $this->getPlanStats($plan['id']); $plan['total_records'] = $stats['total']; $plan['win_count'] = $stats['wins']; $plan['win_rate'] = $stats['total'] > 0 ? round($stats['wins'] / $stats['total'] * 100, 1) : 0; $plan['follower_count'] = $this->db->count('user_follow_plans', [ 'plan_id' => $plan['id'], 'is_active' => 1 ]); } unset($plan); return $plans; } /** * 创建/更新计划 */ public function savePlan(array $data): array { $fields = [ 'game_id' => intval($data['game_id'] ?? 1), 'name' => trim($data['name'] ?? ''), 'plan_type' => trim($data['plan_type'] ?? 'bs'), 'target_rank' => intval($data['target_rank'] ?? 1), 'strategy' => trim($data['strategy'] ?? 'follow'), 'bet_amount' => floatval($data['bet_amount'] ?? 100), 'status' => intval($data['status'] ?? 1), ]; if (empty($fields['name'])) { return ['success' => false, 'message' => '计划名称不能为空']; } $id = intval($data['id'] ?? 0); if ($id > 0) { $this->db->update('follow_plans', $fields, ['id' => $id]); } else { $fields['created_by'] = intval($data['created_by'] ?? 0); $this->db->insert('follow_plans', $fields); $id = intval($this->db->id()); } return ['success' => true, 'id' => $id]; } /** * 删除计划 */ public function deletePlan(int $planId): array { $this->db->delete('follow_plan_records', ['plan_id' => $planId]); $this->db->delete('user_follow_plans', ['plan_id' => $planId]); $this->db->delete('follow_plans', ['id' => $planId]); return ['success' => true]; } /** * 添加计划推荐记录(由 cron 或后台手动触发) */ public function addRecord(int $planId, int $periodId, string $periodNumber, string $recommendValue): array { $exists = $this->db->get('follow_plan_records', 'id', [ 'plan_id' => $planId, 'period_id' => $periodId ]); if ($exists) { return ['success' => false, 'message' => '该期已有推荐记录']; } $this->db->insert('follow_plan_records', [ 'plan_id' => $planId, 'period_id' => $periodId, 'period_number' => $periodNumber, 'recommend_value' => $recommendValue, ]); return ['success' => true, 'id' => intval($this->db->id())]; } /** * 结算推荐记录(开奖后调用) */ public function settleRecord(int $recordId, string $resultValue, bool $isWin): void { $this->db->update('follow_plan_records', [ 'result_value' => $resultValue, 'is_win' => $isWin ? 1 : 0, ], ['id' => $recordId]); // 更新所有跟了这个计划的用户统计 $record = $this->db->get('follow_plan_records', '*', ['id' => $recordId]); if (!$record) return; $plan = $this->db->get('follow_plans', '*', ['id' => $record['plan_id']]); if (!$plan) return; $betAmount = floatval($plan['bet_amount']); $profit = $isWin ? $betAmount * 0.95 : -$betAmount; // 简化盈亏计算 $followers = $this->db->select('user_follow_plans', '*', [ 'plan_id' => $record['plan_id'], 'is_active' => 1 ]); foreach ($followers as $f) { $this->db->update('user_follow_plans', [ 'total_bets[+]' => 1, 'total_wins[+]' => $isWin ? 1 : 0, 'total_profit[+]' => $profit, ], ['id' => $f['id']]); } } }