'>=', 2 => '>', ]; /** * @config * reach_level * grades * - name * - value */ public function saveSetting($params, $promote) { $id = $params['id'] ?? 0; if (empty($params['base_game_id'])) { throw new \Exception('请选择游戏'); } $monthBegin = isset($params['month_begin']) && $params['month_begin'] ? date('Ym', strtotime($params['month_begin'])) : 0; $monthEnd = isset($params['month_end']) && $params['month_end'] ? date('Ym', strtotime($params['month_end'])) : self::FOREVER_TIME; $setting = null; if ($id > 0) { $setting = M('promote_grade_setting', 'tab_')->where(['id' => $id])->find(); if (is_null($setting)) { throw new \Exception('记录不存在'); } if ($setting['company_id'] != $promote['company_id']) { throw new \Exception('不允许修改其他公司的配置'); } } else { $count = $this->getRepeatRuleCount($promote['company_id'], $params['base_game_id'], $monthBegin, $monthEnd); if ($count > 0) { throw new \Exception('该游戏在相同时间段内已经设置规则'); } } if ($monthBegin > 0 && $monthEnd > 0 && $monthBegin > $monthEnd) { throw new \Exception('规则截止时间不能大于规则开始时间'); } $config = []; $config['reach_level'] = $params['level']; $config['grades'] = $this->sortGrades($params['grades']); $config['default_grade_name'] = $params['default_grade_name']; $data = []; $data['status'] = 1; $data['base_game_id'] = $params['base_game_id']; $data['month_begin'] = $monthBegin; $data['month_end'] = $monthEnd; $data['name'] = $params['name']; $data['config'] = json_encode($config); if ($setting) { $data['create_time'] = time(); M('promote_grade_setting', 'tab_')->where(['id' => $id])->save($data); } else { $data['company_id'] = $promote['company_id']; $data['create_time'] = time(); $data['update_time'] = time(); M('promote_grade_setting', 'tab_')->add($data); } } private function sortGrades($grades) { if (count($grades) == 0) { return $grades; } $values = []; $symbols = []; foreach ($grades as $key => $row) { $values[$key] = $row['value']; $symbols[$key] = $row['symbol']; } array_multisort($values, SORT_ASC, $symbols, SORT_ASC, $grades); return $grades; } public function getTimeRepeatCondition($monthBegin, $monthEnd) { return ' ((month_begin >= ' . $monthBegin . ' AND month_begin <= ' . $monthEnd . ') OR (month_begin <= ' . $monthBegin . ' AND month_end >= ' . $monthEnd . ') OR (month_end >= ' . $monthBegin . ' AND month_end <= ' . $monthEnd . '))'; } public function getRepeatRuleCount($companyId, $baseGameId, $monthBegin, $monthEnd) { $conditions = [ 'compnay_id' => $companyId, 'base_game_id' => $baseGameId, ]; $conditions['_string'] = $this->getTimeRepeatCondition($monthBegin, $monthEnd); $count = M('promote_grade_setting', 'tab_')->where($conditions)->count(); return intval($count); } public function getCurrentSetting($promote, $baseGameId, $month) { $timeCondition = 'month_end >= ' . $month . ' and month_begin <= ' . $month; return M('promote_grade_setting', 'tab_') ->where([ 'status' => 1, 'company_id' => $promote['company_id'], 'base_game_id' => $baseGameId, '_string' => $timeCondition ]) ->find(); } public function searchGradeByPromotes($promotes, $params, $setting) { $config = json_decode($setting['config'], true); $settingLevel = $config['reach_level']; $month = $params['month'] ?? date('Y-m'); $baseGameId = $params['base_game_id'] ?? 0; $promoteIds = array_column($promotes, 'id'); $beginTime = strtotime($month . '-01 00:00:00'); $endDate = date('Y-m-01 00:00:00', strtotime($month . '-01' . ' +1 month')); $endTime = strtotime($endDate) - 1; $betweenTime = [$beginTime, $endTime]; $userSubSql = M('user', 'tab_') ->field(['id']) ->where(['register_time' => ['between', $betweenTime], 'promote_id' => ['in', $promoteIds]]) ->group('promote_id') ->select(false); $baseGame = null; if ($baseGameId > 0) { $baseGame = M('base_game', 'tab_')->where(['id' => $baseGameId])->find(); } $roleMap = [ 'role_level' => ['egt', $settingLevel], 'create_time' => ['between', $betweenTime], 'promote_id' => ['in', $promoteIds], '_string' => 'user_id in (' . $userSubSql . ')' ]; $spendRepository = new SpendRepository(); $spendMap = [ 'pay_time' => ['between', $betweenTime], 'pay_status' => 1, 'promote_id' => ['in', $promoteIds], '_string' => 'user_id in (' . $userSubSql . ')' ]; $spendMap = $spendRepository->withIsCheck($spendMap); if ($baseGame) { $roleMap['game_id'] = ['in', [$baseGame['android_game_id'], $baseGame['ios_game_id']]]; $spendMap['game_id'] = ['in', [$baseGame['android_game_id'], $baseGame['ios_game_id']]]; } else { $roleMap['_string'] .= ' and 1=0'; $spendMap['_string'] .= ' and 1=0'; } $accountItems = M('user_play_info', 'tab_') ->field(['promote_id', 'count(DISTINCT user_id) num']) ->where($roleMap) ->group('promote_id') ->select(); $accountItems = index_by_column('promote_id', $accountItems); $amountItems = M('spend', 'tab_') ->field(['promote_id', 'sum(pay_amount) amount']) ->where($spendMap) ->group('promote_id') ->select(); $amountItems = index_by_column('promote_id', $amountItems); $promoteService = new PromoteService(); $records = []; foreach ($promotes as $promote) { $amountItem = $amountItems[$promote['id']] ?? null; $accountItem = $accountItems[$promote['id']] ?? null; $amount = $amountItem ? $amountItem['amount'] : 0; $num = $accountItem ? $accountItem['num'] : 0; $value = $num == 0 ? 0 : round($amount / $num, 2); $records[] = [ 'id' => $promote['id'], 'level' => $promote['level'], 'amount' => $amount, 'num' => $num, 'real_name' => hideRealName($promote['real_name']), 'account' => $promote['account'], 'promote_group' => $promoteService->getGroupNameByChain($promote['chain'], $promote['id']), 'value' => $value, 'grade_name' => $this->getGradeByValue($value, $setting), 'current_display' => '' ]; } return $records; } public function getGradeByValue($value, $setting) { $config = json_decode($setting['config'], true); $grades = $config['grades']; $gradeName = $config['default_grade_name']; foreach ($grades as $key => $grade) { if ($key == 0 && !$this->isBigger($value, $grade)) { $gradeName = $config['default_grade_name']; break; } $nextGrade = $grades[$key + 1] ?? null; if ($this->isBigger($value, $grade) && !$this->isBigger($value, $nextGrade)) { $gradeName = $grade['name']; break; } } return $gradeName; } private function isBigger($value, $grade) { if (is_null($grade)) { return false; } if ($grade['symbol'] == 1 && $value >= $grade['value']) { return true; } elseif ($grade['symbol'] == 2 && $value > $grade['value']) { return true; } return false; } }