editMessageText($returnMsg); } break; } } /** * @description: 获取查询条件 * @param {array} $search 查询内容 * @return {array} */ public static function getWhere(array $search = []): array { $where = []; if (isset($search['coin']) && !empty($search['coin'])) { $where[] = ['coin', '=', $search['coin']]; } if (isset($search['net']) && !empty($search['net'])) { $where[] = ['net', '=', $search['net']]; } if (isset($search['address']) && !empty($search['address'])) { $where[] = ['address', '=', $search['address']]; } if (isset($search['id']) && !empty($search['id'])) { $where[] = ['id', '=', $search['id']]; } if (isset($search['member_id']) && !empty($search['member_id'])) { $where[] = ['member_id', '=', $search['member_id']]; } if (isset($search['type']) && !empty($search['type'])) { $where[] = ['type', '=', $search['type']]; } if (isset($search['change_type']) && !empty($search['change_type'])) { $where[] = ['change_type', '=', $search['change_type']]; } if (isset($search['start_time']) && !empty($search['start_time'])) { $where[] = ['created_at', '>=', "{$search['start_time']} 00:00:00"]; $where[] = ['created_at', '<=', "{$search['end_time']} 23:59:59"]; } return $where; } /** * @description: 查询单条数据 * @param array $search * @return \App\Models\Coin|null */ public static function findOne(array $search): ?BalanceLog { return static::model()::where(static::getWhere($search))->first(); } /** * @description: 查询所有数据 * @param array $search * @return \Illuminate\Database\Eloquent\Collection */ public static function findAll(array $search = []) { return static::model()::where(static::getWhere($search))->get(); } /** * @description: 分页查询 * @param array $search * @return array */ public static function paginate(array $search = []): array { $limit = isset($search['limit']) ? $search['limit'] : 15; $paginator = static::model()::where(static::getWhere($search)) ->when(isset($search['change_types']) && !empty($search['change_types']), function ($query) use ($search) { return $query->whereIn('change_type', $search['change_types']); }) ->orderBy('updated_at', 'desc') ->paginate($limit); return ['total' => $paginator->total(), 'data' => $paginator->items()]; } /** * @description: 生成资金变动日志 * @param {*} $memberId * @param {*} $amount * @param {*} $before_balance * @param {*} $after_balance * @param {*} $change_type * @param {*} $related_id * @param {*} $remark * @return {*} */ public static function addLog($memberId, $amount, $before_balance, $after_balance, $change_type, $related_id, $remark, $room_id = null) { //回水相关 if (in_array($change_type, static::$computeBackFlowChangeTypes)) { BackflowService::updateOrCreate((string)$memberId, floatval($amount)); } $data = []; $data['member_id'] = $memberId; $data['amount'] = $amount; $data['before_balance'] = $before_balance; $data['after_balance'] = $after_balance; $data['change_type'] = $change_type; $data['related_id'] = $related_id; $data['remark'] = $remark; if ($room_id) $data['room_id'] = $room_id; $result = static::$MODEL::create($data); //充值返现活动 if ( in_array($change_type, ['充值','人工充值','三方充值'])) { $user = User::where('member_id', $memberId)->first(); //充值更新用户等级 $total_recharge = self::getTotalRecharge($memberId); $total_recharge = bcadd($total_recharge, $amount, 2); $level = self::calculateLevel($total_recharge); if ($level > $user->level) { $user->level = $level; $user->save(); } $remark_amount = bcadd($amount, 0, 2); //返现比例(给邀请人返现) $rate = Config::where('field', 'recharge_rate')->first()->val ?? 0; $add_amount = bcmul($amount, $rate/100, 2); if ($add_amount > 0) { //被邀请人每次充值,都给邀请人返现,直接可用余额 $agent_user_code = $user->agent_user_code; if (!empty($agent_user_code)) { $agent_member_id = User::where('user_code', $agent_user_code)->first()->member_id; if (!empty($agent_member_id)) { $balanceData = WalletService::updateBalance($agent_member_id, $add_amount); BalanceLogService::addLog($agent_member_id, $add_amount, $balanceData['before_balance'], $balanceData['after_balance'], '充值返现', $related_id, '被邀请人:'.$memberId."充值金额为:{$remark_amount}"); } } } $walletInfo = Wallet::where('member_id', $memberId)->first(); //即充即送-返彩活动 $bonusAmount = self::calculateRechargeBonus($amount,$memberId, $related_id); if ($bonusAmount > 0) { static::$MODEL::create([ 'type' => 2, 'member_id' => $memberId, 'amount' => $bonusAmount, 'before_balance' => $walletInfo->frozen_balance, 'after_balance' => bcadd($walletInfo->frozen_balance, $bonusAmount, 2), 'change_type' => '即充即送', 'frozen_status' => 1, 'related_id' => $related_id, 'remark' => '充值金额为:'.$remark_amount, ]); $walletInfo->frozen_balance = bcadd($walletInfo->frozen_balance, $bonusAmount, 2); } //老用户回归-返彩活动 $bonusAmount = self::calculateUserReturnRechargeBonus($amount,$memberId, $level, $related_id); if ($bonusAmount > 0) { static::$MODEL::create([ 'type' => 2, 'member_id' => $memberId, 'amount' => $bonusAmount, 'before_balance' => $walletInfo->frozen_balance, 'after_balance' => bcadd($walletInfo->frozen_balance, $bonusAmount, 2), 'change_type' => '老用户回归', 'frozen_status' => 1, 'related_id' => $related_id, 'remark' => '充值金额为:'.$remark_amount, ]); $walletInfo->frozen_balance = bcadd($walletInfo->frozen_balance, $bonusAmount, 2); } $walletInfo->save(); } return $result; } /** * 获取用户累计充值金额 */ public static function getTotalRecharge($memberId): float { return static::$MODEL::where('member_id', $memberId)->where('type',1)->whereIn('change_type', ['充值','人工充值', '三方充值'])->sum('amount'); } /** * 根据历史累计充值金额计算等级 * @param float $totalAmount 历史累计充值金额 * @return int 等级(1-5) */ public static function calculateLevel(float $totalAmount): int { $levelList = Level::orderBy('recharge', 'desc')->get()->toArray(); foreach ($levelList as $item) { if ($totalAmount >= $item['recharge']) { return $item['level']; } } return 0; } /** * @description: 获取今日流水 * @param int $memberId * @param string|null $date * @return {*} */ public static function getTodayFlowing($memberId, $date = null) { if (!$date) { $date = date('Y-m-d'); } $startTime = date('Y-m-d H:i:s', strtotime($date . ' 00:00:00')); $endTime = date('Y-m-d H:i:s', strtotime($date . ' 23:59:59')); $flow = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '投注') ->sum('amount'); $refund = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '返水') ->sum('amount'); $profit = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '中奖') //嬴正数 输负数 ->sum('amount'); $walletInfo = WalletService::model()::where('member_id', $memberId)->first(); $text = ''; $text .= "当日流水: " . number_format((0 - $flow), 2) . "\n"; $text .= "返水额度: " . number_format($refund, 2) . "\n"; $text .= "当日盈亏: " . number_format(($profit + $refund + $flow), 2) . "\n"; $text .= "余额: " . number_format($walletInfo['available_balance'], 2) . "\n"; return [ 'chat_id' => $memberId, 'text' => $text ]; } public static function getFlowingHistory($memberId, $messageId = null, $page = 1, $limit = 5) { $dateTime = date('Y-m-d 00:00:00'); $list = []; for ($i = 0; $i < $limit; $i++) { $newIndex = ($page - 1) * $limit + $i; $date = date('Y-m-d', strtotime($dateTime . " -{$newIndex} day")); $startTime = date('Y-m-d H:i:s', strtotime($date . ' 00:00:00')); $endTime = date('Y-m-d H:i:s', strtotime($date . ' 23:59:59')); $flow = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '投注') ->sum('amount'); $refund = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '返水') ->sum('amount'); $profit = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [$startTime, $endTime]) ->where('change_type', '中奖') //嬴正数 输负数 ->sum('amount'); $list[] = [ 'date' => $date, 'flow' => number_format($flow, 2), 'refund' => number_format($refund, 2), 'profit' => number_format(($profit + $refund + $flow), 2) ]; } // $startTime = date('Y-m-d H:i:s',strtotime($date . ' 00:00:00')); // $endTime = date('Y-m-d H:i:s',strtotime($date . ' 23:59:59')); // $list = static::model()::where('member_id', $memberId) // ->whereBetween('created_at', [$startTime, $endTime]) // ->orderBy('created_at', 'desc') // ->get(); $text = lang("流水历史") . " \n"; foreach ($list as $item) { $text .= "---------------------\n"; $text .= lang("日期") . ": {$item['date']} \n"; $text .= lang("流水") . ": {$item['flow']} \n"; $text .= lang("返水") . ": {$item['refund']} \n"; $text .= lang("盈利") . ": {$item['profit']} \n"; } $keyboard = [[ ['text' => "👇" . lang("下一页"), 'callback_data' => "FlowingHistoryPage@@" . ($page + 1)] ]]; if ($page > 1) { array_unshift($keyboard[0], ['text' => "👆" . lang("上一页"), 'callback_data' => "FlowingHistoryPage@@" . ($page - 1)]); } return [ 'chat_id' => $memberId, 'text' => $text, 'message_id' => $messageId, 'reply_markup' => json_encode(['inline_keyboard' => $keyboard]), ]; } /** * 计算充值的返现金额 * @param float $amount 充值金额(人民币) */ public static function calculateRechargeBonus($amount,$memberId, $related_id = null) { $activity = ActivityReward::where('lang','zh')->where('type',3)->where('status',1)->where('start_time', '<', time())->where('end_time', '>', time())->first(); if (!$activity) { return false; } $params = $activity->params ? json_decode($activity->params, true) : []; if (!$params || empty($params['reward_ratio'])) { return false; } // 规则1:单笔最低金额 if (isset($params['min_recharge_amount']) && $amount < $params['min_recharge_amount']) { return false; } // 规则2:必须是每日前几笔充值 if (!empty($params['reward_limit_count'])) { //今日已充值数 $dailyOrder = static::model()::where('member_id', $memberId) ->whereBetween('created_at', [date('Y-m-d 00:00:00'), date('Y-m-d 23:59:59')]) ->whereIn('change_type', ['充值','三方充值']) ->count(); if ($dailyOrder > $params['reward_limit_count']) { return false; } } // 规则3:返彩比例,不超过单笔最高10000元 $rate = bcdiv($params['reward_ratio'], 100, 6); // 0.5% $maxBonus = $params['max_reward_amount'] ?? 10000; // 单笔最高上限 $calculatedBonus = bcmul($amount, $rate, 2); // 保留两位小数 $bonusAmount = min($calculatedBonus, $maxBonus); //倍率流水 $need_flow = !empty($params['reward_turnover_ratio']) ? bcmul($bonusAmount, $params['reward_turnover_ratio'], 2) : $bonusAmount; //返彩流水 WalletBonus::addData($memberId, 1, $bonusAmount, $activity->id, $related_id, $need_flow); return $bonusAmount; } /** * 计算老用户回归当日的充值返现金额 * @param float $amount 充值金额(人民币) */ public static function calculateUserReturnRechargeBonus($amount,$memberId, $level, $related_id = null) { $activity = ActivityReward::where('lang','zh')->where('type',4)->where('status',1)->where('start_time', '<', time())->where('end_time', '>', time())->first(); if (!$activity) { return false; } $params = $activity->params ? json_decode($activity->params, true) : []; if (!$params || empty($params['no_login_days']) || empty($params['reward_rules'])) { return false; } // 规则1:单笔最低金额 if (isset($params['min_amount']) && $amount < $params['min_amount']) { return false; } // 规则2:多少天未登录 $noLoginDays = UserLogin::getNotLoginDays($memberId); if ($noLoginDays < $params['no_login_days']) { return false; } foreach($params['reward_rules'] as $rule) { if (isset($rule['start_level']) && isset($rule['end_level'])) { if ($level >= $rule['start_level'] && $level <= $rule['end_level']) { $bonusAmount = $rule['bonus']; //倍率流水 $need_flow = !empty($rule['turnover_rate']) ? bcmul($bonusAmount, $rule['turnover_rate'], 2) : $bonusAmount; break; } } } if (!isset($bonusAmount)) { return false; } //返彩流水 WalletBonus::addData($memberId, 3, $bonusAmount, $activity->id, $related_id, $need_flow); return $bonusAmount; } }