[], 'budget' => null, 'reward_quota' => null, 'sort' => 0, 'register_time_limited' => false, 'register_start_time' => null, 'register_end_time' => null, 'register_platforms' => [], 'deposit_limited' => false, 'deposit_min' => null, 'deposit_max' => null, 'show_ineligible' => true, ]; } private static function configuration(array $params, ?ActivityReward $existing): array { $defaults = static::configurationDefaults(); if ((int)($params['type'] ?? $existing?->type) === 2) { return $defaults; } $quotaMode = !$existing || $existing->quota_enabled; Validator::make($params, [$quotaMode ? 'budget' : 'reward_quota' => ['prohibited']])->validate(); $previous = $existing ? $existing->only(array_keys($defaults)) : []; foreach (['publish_platforms', 'register_platforms'] as $field) { if (($previous[$field] ?? null) === null) $previous[$field] = []; } $config = array_replace($defaults, $previous, array_intersect_key($params, $defaults)); if ($quotaMode) $config['budget'] = null; else $config['reward_quota'] = null; if (empty($config['register_time_limited'])) { $config['register_start_time'] = $config['register_end_time'] = null; } if (empty($config['deposit_limited'])) { $config['deposit_min'] = $config['deposit_max'] = null; } $money = ['nullable', 'numeric', 'min:0', 'regex:/^\d{1,12}(\.\d{1,2})?$/']; Validator::make($config, [ 'publish_platforms' => ['present', 'array'], 'publish_platforms.*' => ['required', 'string', 'distinct', Rule::in(['PC', 'H5', 'APP'])], 'reward_quota' => ['nullable', 'integer', 'min:0', 'max:2147483647'], 'budget' => $money, 'sort' => ['required', 'integer', 'min:0', 'max:4294967295'], 'register_time_limited' => ['required', 'boolean'], 'register_start_time' => ['nullable', 'required_if:register_time_limited,1', 'date'], 'register_end_time' => ['nullable', 'required_if:register_time_limited,1', 'date', 'after_or_equal:register_start_time'], 'register_platforms' => ['present', 'array'], 'register_platforms.*' => ['required', 'string', 'distinct', Rule::in(['PC', 'H5', 'APP'])], 'deposit_limited' => ['required', 'boolean'], 'deposit_min' => array_merge($money, ['required_if:deposit_limited,1']), 'deposit_max' => array_merge($money, ['required_if:deposit_limited,1', 'gte:deposit_min']), 'show_ineligible' => ['required', 'boolean'], ])->validate(); foreach (['budget', 'deposit_min', 'deposit_max'] as $field) { if ($config[$field] !== null) { $config[$field] = bcadd((string)$config[$field], '0', 2); } } if ($config['reward_quota'] !== null) $config['reward_quota'] = (int)$config['reward_quota']; foreach (['register_start_time', 'register_end_time'] as $field) { if ($config[$field] !== null) { $config[$field] = date('Y-m-d H:i:s', strtotime($config[$field])); } } return $config; } /** * @description: 查询单条数据 * @param array $search * @return ActivityReward|null */ public static function findOne(array $search): ActivityReward|null { return static::$MODEL::where(static::getWhere($search))->first(); } public static function activeForMember(int $type, $memberId): ?ActivityReward { $context = ActivityEligibilityService::memberContext($memberId); $activities = ActivityReward::where('lang', 'zh')->where('type', $type)->where('status', 1) ->where('start_time', '<=', time())->where('end_time', '>=', time()) ->orderByDesc('sort')->orderByDesc('id')->get(); foreach ($activities as $activity) { if (!ActivityEligibilityService::evaluate($activity, $context)['is_eligible']) continue; if (!ActivityQuotaService::canAward($activity, $memberId)) continue; return $activity; } return null; } public static function getWhere(array $search = []): array { $where = []; if (isset($search['id']) && !empty($search['id'])) { $where[] = ['id', '=', $search['id']]; } if (isset($search['status']) && $search['status'] != '') { $where[] = ['status', '=', $search['status']]; } if (isset($search['type']) && $search['type'] != '') { $where[] = ['type', '=', $search['type']]; } if (isset($search['title']) && !empty($search['title'])) { $where[] = ['title', 'like', "%{$search['title']}%"]; } if (isset($search['start_time']) && !empty($search['start_time'])) { if (is_array($search['start_time'])) { if (count($search['start_time']) == 2) { $where[] = ['start_time', $search['start_time'][0], $search['start_time'][1]]; } else { $where[] = ['start_time', '=', $search['start_time'][0]]; } } else { $where[] = ['start_time', '=', $search['start_time']]; } } if (isset($search['end_time']) && !empty($search['end_time'])) { if (is_array($search['end_time'])) { if (count($search['end_time']) == 2) { $where[] = ['end_time', $search['end_time'][0], $search['end_time'][1]]; } else { $where[] = ['end_time', '=', $search['end_time'][0]]; } } else { $where[] = ['end_time', '=', $search['end_time']]; } } return $where; } public static function deleteAll(array $search = []): bool { $count = static::$MODEL::where(static::getWhere($search))->delete(); if ($count < 1) throw new Exception('删除失败', HttpStatus::CUSTOM_ERROR); return true; } /** * Update or create * @param array $params * @return bool * @throws Exception */ public static function submit(array $params = []): bool { $info = !empty($params['id']) ? static::findOne(['id' => $params['id']]) : null; if (!empty($params['id']) && !$info) throw new Exception('操作失败', HttpStatus::CUSTOM_ERROR); $params = array_merge($params, static::configuration($params, $info)); unset($params['rewarded_count'], $params['quota_enabled'], $params['budget_used']); // Server-owned fields. if (isset($params['start_time'])) $params['start_time'] = strtotime($params['start_time']); if (isset($params['end_time'])) $params['end_time'] = strtotime($params['end_time']); if (isset($params['detail_image'])) $params['detail_image'] = Util::replacePartInUrl($params['detail_image']); if (isset($params['pc_image'])) $params['pc_image'] = Util::replacePartInUrl($params['pc_image']); if (isset($params['detail_banner'])) $params['detail_banner'] = Util::replacePartInUrl($params['detail_banner']); if (isset($params['pc_banner'])) $params['pc_banner'] = Util::replacePartInUrl($params['pc_banner']); if (!empty($params['id'])) { $info->update($params); } else { $info = new ActivityReward($params); $info->quota_enabled = true; // Existing rows stay false; clients cannot change the mode. $info->save(); } return true; } public static function promotionalActivity($chatId): array { $keyboard = []; $url = Config::where('field','activity_home_url')->first()->val; $url.="?member_id=".$chatId; $keyboard[] = [ ['text'=>'活动首页','url'=>$url] ]; $msg = []; $msg['chat_id'] = $chatId; $msg['text'] = "点击下方按钮进入活动首页"; $msg['reply_markup'] = json_encode(['inline_keyboard' => $keyboard]); return $msg; } //F1bet娱乐更多玩法(足球首页) public static function footballUrl($chatId): array { $token = UserSession::setToken($chatId); $is_bind = User::where('member_id', $chatId)->value('account') ? 1 : 0; $keyboard = []; $url = Config::where('field','football_home_url ')->first()->val; $url.="?token=".$token."&is_bind=".$is_bind; $keyboard[] = [ ['text'=>'F1bet娱乐首页','url'=>$url] ]; $msg = []; $msg['chat_id'] = $chatId; $msg['text'] = "点击下方按钮进入F1bet娱乐首页"; $msg['reply_markup'] = json_encode(['inline_keyboard' => $keyboard]); return $msg; } }