request->getJSON(true); if (!isset($request['compId'])) { return $this->respond([ 'status' => 'fail', 'message' => 'filter(compId)가 누락되었습니다.' ], 400); } $status = isset($request['status']) ? $request['status'] : null; $compId = $request['compId']; // 쿼리 빌더 $builder = $db->table('EVT_LIST'); // compId가 '0-000000'이 아닐 때만 COMP_ID 조건 추가 if ($compId !== '0-000000') { $builder->where('COMP_ID', $compId); } if ($status !== null) { // status가 넘어오면 해당 값만 검색 $builder->where('status', $status); } $lists = $builder->get()->getResultArray(); foreach ($lists as &$row) { if (isset($row['STARTDATE']) && !empty($row['STARTDATE'])) { $row['STARTDATE'] = date('Y-m-d', strtotime($row['STARTDATE'])); } if (isset($row['ENDDATE']) && !empty($row['ENDDATE'])) { $row['ENDDATE'] = date('Y-m-d', strtotime($row['ENDDATE'])); } } // 반환 데이터 가공 (필요시) $filtered = array_reverse($lists); return $this->respond($filtered, 200); } //이벤트 마감 체크 public function winnerChk() { $db = \Config\Database::connect(); $seq = null; $requestJson = $this->request->getJSON(true); if (is_array($requestJson) && isset($requestJson['seq'])) { $seq = $requestJson['seq']; } if (empty($seq)) { return $this->respond(['status' => 'fail', 'message' => '필수 파라미터 누락'], 400); } // EVT_ITEM에서 해당 seq 로 아이템과 WIN_QTY 조회 $items = $db->table('EVT_ITEM') ->select('ITEM_SEQ, WIN_QTY') ->where('EVT_SEQ', $seq) ->get()->getResultArray(); // 아이템별 최대 당첨자수 배열 구성 $maxWinners = []; foreach ($items as $idx => $item) { $rank = $idx + 1; // 1등부터 시작 $maxWinners[$rank] = (int)$item['WIN_QTY']; } // PARTICIPATION_LIST에서 seq로 당첨자 집계 (RANK별 COUNT) $counts = []; $results = $db->table('PARTICIPATION_LIST') ->select('RANK, COUNT(*) as cnt') ->where('EVT_SEQ', $seq) ->groupBy('RANK') ->get()->getResultArray(); foreach ($results as $row) { $counts[(int)$row['RANK']] = (int)$row['cnt']; } // 모든 RANK의 당첨자수가 max와 같거나 크면 "마감" $isClosed = true; foreach ($maxWinners as $rank => $qty) { $curr = isset($counts[$rank]) ? $counts[$rank] : 0; if ($curr < $qty) { $isClosed = false; break; } } if ($isClosed) { return $this->respond(['status' => 'closed', 'message' => '마감되었습니다'], 200); } else { return $this->respond(['status' => 'open', 'message' => '아직 마감 아님'], 200); } } //당첨자 등록 및 랭크 반환 public function winnerReg() { $db = \Config\Database::connect(); // 파라미터 추출 $seq = null; $name = null; $phone = null; $request = $this->request->getJSON(true); if (is_array($request) && isset($request['seq'])) { $seq = $request['seq']; $name = $request['name']; $phone = $request['phone']; } else { $seq = $this->request->getPost('seq'); $name = $this->request->getPost('name'); $phone = $this->request->getPost('phone'); } // 등수별 설정 및 ITEM_NAME 매핑 $rankConfigs = []; $itemNames = []; if (!empty($seq)) { $builder = $db->table('EVT_ITEM'); $builder->select('WIN_RATE, WIN_QTY, ITEM_NAME'); $builder->where('EVT_SEQ', $seq); $builder->orderBy('ITEM_SEQ', 'ASC'); $rows = $builder->get()->getResultArray(); foreach ($rows as $i => $row) { $rank = $i + 1; // 1등부터 시작 $rankConfigs[$rank] = [ 'percent' => (int)$row['WIN_RATE'], 'max' => (int)$row['WIN_QTY'] ]; $itemNames[$rank] = $row['ITEM_NAME']; } } // 등수별 참여자 집계 $builder = $db->table('PARTICIPATION_LIST') ->select('RANK, COUNT(*) AS cnt') ->where('EVT_SEQ', $seq) ->groupBy('RANK'); $result = $builder->get()->getResultArray(); $winnerCounts = []; foreach ($result as $row) { $winnerCounts[(int)$row['RANK']] = (int)$row['cnt']; } // 가능한 등수 구하기 $availableRanks = []; $totalPercent = 0; foreach ($rankConfigs as $rank => $cfg) { $cnt = isset($winnerCounts[$rank]) ? $winnerCounts[$rank] : 0; if ($cnt < $cfg['max']) { $availableRanks[] = [ 'rank' => $rank, 'percent' => $cfg['percent'] ]; $totalPercent += $cfg['percent']; } } // if (empty($availableRanks)) { // return $this->respond(['status' => 'fail', 'message' => '모든 등수 당첨자가 마감되었습니다.'], 200); // } if (empty($availableRanks)) { // 등수 마감 상태 => rank 0으로 처리 $selectedRank = 0; $selectedItemName = "꽝"; $rankIndex = 0; } else { // 기존 랜덤 등수 추출 $rand = mt_rand() / mt_getrandmax() * $totalPercent; foreach ($availableRanks as $cfg) { if ($rand < $cfg['percent']) { $selectedRank = $cfg['rank']; break; } $rand -= $cfg['percent']; } if (!isset($selectedRank)) { $selectedRank = $availableRanks[count($availableRanks) - 1]['rank']; } $selectedItemName = isset($itemNames[$selectedRank]) ? $itemNames[$selectedRank] : null; // RANK_INDEX 구하기 $builder = $db->table('PARTICIPATION_LIST'); $builder->selectMax('RANK_INDEX'); $builder->where('EVT_SEQ', $seq); $builder->where('RANK', $selectedRank); $rankIndexRow = $builder->get()->getRowArray(); $rankIndex = isset($rankIndexRow['RANK_INDEX']) && $rankIndexRow['RANK_INDEX'] ? ((int)$rankIndexRow['RANK_INDEX']) + 1 : 1; } // DB 저장 $insertData = [ 'EVT_SEQ' => $seq, 'RANK' => $selectedRank, 'ITEM_NAME' => $selectedItemName, 'NAME' => $name, 'PHONE' => $phone, 'RANK_INDEX' => $rankIndex, 'PRIVACY_AGREE' => 1, 'THIRDPARTY_AGREE' => 1 ]; $db->table('PARTICIPATION_LIST')->insert($insertData); // 응답 return $this->respond([ 'rank' => $selectedRank, 'item_name' => $selectedItemName, 'rank_index' => $rankIndex, 'name' => $name, 'phone' => $phone, ], 200); } //아이템 리스트 public function itemCount() { $db = \Config\Database::connect(); // POST 파라미터 JSON 또는 폼에서 받기 (JSON 우선) $seq = null; $request = $this->request->getJSON(true); if (is_array($request) && isset($request['seq'])) { $seq = $request['seq']; } else { $seq = $this->request->getPost('seq'); // 폼 방식 대비 } if (empty($seq)) { return $this->respond(['status' => 'fail', 'message' => 'seq 파라미터가 필요합니다.'], 400); } $builder = $db->table('EVT_ITEM'); $builder->select('ITEM_NAME'); $builder->where('EVT_SEQ', $seq); $query = $builder->get(); $items = []; foreach ($query->getResultArray() as $row) { $items[] = $row['ITEM_NAME']; } $count = count($items); return $this->respond([ 'count' => $count, 'items' => $items ], 200); } //당첨자 상세 public function winnerDetail($seq) { $db = \Config\Database::connect(); // 이벤트 + 아이템 목록 조인 조회 $builder = $db->table('EVT_LIST E'); $builder->join('EVT_ITEM I', 'E.SEQ = I.EVT_SEQ', 'left'); $builder->join('PARTICIPATION_LIST P', 'E.SEQ = P.EVT_SEQ', 'left'); $builder->select( 'E.SEQ, E.TITLE, E.STARTDATE, E.ENDDATE, E.REGDATE, ' . 'I.ITEM_SEQ, I.ITEM_NAME AS ITEM_ITEM_NAME, I.WIN_QTY, I.WIN_RATE,' . 'P.PART_SEQ, P.RANK, P.ITEM_NAME AS PART_ITEM_NAME, P.ID, P.NAME, P.PHONE, P.WINNER_DATE, P.RANK_INDEX, P.PRIVACY_AGREE, P.THIRDPARTY_AGREE' ); $builder->where('E.SEQ', $seq); $rows = $builder->get()->getResultArray(); if (empty($rows)) { return $this->respond(['status' => 'fail', 'message' => '해당 이벤트가 없습니다.'], 404); } // 이벤트(게시글) 정보와 아이템 배열로 가공하여 응답 $event = [ 'seq' => $rows[0]['SEQ'], 'title' => $rows[0]['TITLE'], 'startdate' => date('Y-m-d', strtotime( $rows[0]['STARTDATE'])), 'enddate' => date('Y-m-d', strtotime( $rows[0]['ENDDATE'])), 'regdate' =>date('Y-m-d', strtotime( $rows[0]['REGDATE'])), 'items' => [], 'participations' => [], 'participations_cal' => [] ]; // 중복방지용 $itemSeqSet = []; $partSeqSet = []; foreach ($rows as $row) { // 아이템 중복 체크 및 추가 if ($row['ITEM_SEQ'] !== null && !isset($itemSeqSet[$row['ITEM_SEQ']])) { $event['items'][] = [ 'item_seq' => $row['ITEM_SEQ'], 'name' => $row['ITEM_ITEM_NAME'], // 반드시! EVT_ITEM 테이블의 컬럼명 별칭 'qty' => $row['WIN_QTY'], 'rate' => $row['WIN_RATE'] ]; $itemSeqSet[$row['ITEM_SEQ']] = true; } // 참여자 중복 체크 및 추가 if ($row['PART_SEQ'] !== null && !isset($partSeqSet[$row['PART_SEQ']])) { $event['participations'][] = [ 'part_seq' => $row['PART_SEQ'], 'rank' => $row['RANK'], 'item_name' => $row['PART_ITEM_NAME'], 'id' => $row['ID'], 'name' => $row['NAME'], 'phone' => $row['PHONE'], 'winner_date' => $row['WINNER_DATE'] = date('Y-m-d', strtotime($row['WINNER_DATE'])), 'rank_index' => $row['RANK_INDEX'], 'privacy_agree' => $row['PRIVACY_AGREE'], 'thirdparty_agree' => $row['THIRDPARTY_AGREE'] ]; $partSeqSet[$row['PART_SEQ']] = true; } } // 중복되는 rank에서 part_seq가 가장 낮은 값만 participations_cal에 담기 // 유니크 참여자 배열 만들기 $participations = []; foreach ($rows as $row) { if ( !array_key_exists('PART_SEQ', $row) || !array_key_exists('RANK', $row) || $row['PART_SEQ'] === null || $row['RANK'] === null || $row['RANK'] == 0 ) { continue; } $participations[$row['PART_SEQ']] = $row; } // 등수별 인원수 카운트 $rankCounts = []; foreach ($participations as $part) { $rank = $part['RANK']; if (!isset($rankCounts[$rank])) { $rankCounts[$rank] = 0; } $rankCounts[$rank]++; } // 중복 등수에서 part_seq가 가장 낮은 값만 participations_cal에 담기 (참여자 기준) $rankMinPartSeq = []; foreach ($participations as $part) { $rank = $part['RANK']; $partSeq = $part['PART_SEQ']; if (!isset($rankMinPartSeq[$rank]) || $partSeq < $rankMinPartSeq[$rank]['part_seq']) { $rankMinPartSeq[$rank] = [ 'part_seq' => $partSeq, 'rank' => $part['RANK'], 'item_name' => $part['PART_ITEM_NAME'], 'id' => $part['ID'], 'name' => $part['NAME'], 'phone' => $part['PHONE'], 'winner_date' => $part['WINNER_DATE'], 'rank_index' => $part['RANK_INDEX'], 'privacy_agree' => $part['PRIVACY_AGREE'], 'thirdparty_agree' => $part['THIRDPARTY_AGREE'], 'count' => $rankCounts[$rank] ]; } } $event['participations_cal'] = array_values($rankMinPartSeq); return $this->respond($event, 200); } //참여자 리스트 public function getParticipationByItem() { $db = \Config\Database::connect(); $request = $this->request->getJSON(true); // 파라미터 추출 $seq = isset($request['seq']) ? $request['seq'] : null; $itemName = isset($request['item_name']) ? $request['item_name'] : null; if (empty($seq)) { return $this->respond(['status' => 'fail', 'message' => 'seq는 필수입니다.'], 400); } // PARTICIPATION_LIST에서 EVT_SEQ와 ITEM_NAME으로 필터링 $builder = $db->table('PARTICIPATION_LIST'); $builder->where('EVT_SEQ', $seq); if (!empty($itemName)) { $builder->where('ITEM_NAME', $itemName); } $filterList = $builder->get()->getResultArray(); // 키를 모두 소문자로 변환 $filterListLower = []; foreach ($filterList as $row) { $filterListLower[] = array_change_key_case($row, CASE_LOWER); } return $this->respond([ 'status' => 'success', 'list' => $filterListLower ], 200); } // 이벤트 참가 여부 체크 public function matchedUser() { $data = $this->request->getJSON(true); $seq = $data['seq'] ?? null; $name = $data['name'] ?? null; $phone = $data['phone'] ?? null; if (!$seq || !$name || !$phone) { return $this->fail('필수 값이 누락되었습니다.', 400); } $db = \Config\Database::connect(); $builder = $db->table('PARTICIPATION_LIST'); $existing = $builder ->where('EVT_SEQ', $seq) ->where('NAME', $name) ->where('PHONE', $phone) ->get() ->getRowArray(); if ($existing) { // 동일한 사람이 이미 존재할 경우 return $this->respond([ 'result' => 'matched' ]); } $phoneSame = $builder ->where('EVT_SEQ', $seq) ->where('NAME !=', $name) ->where('PHONE', $phone) ->get() ->getRowArray(); if ($phoneSame) { return $this->respond([ 'result' => 'phonesame' ]); } // 일치하는 정보가 없을 때 (필요에 따라 처리) return $this->respond([ 'result' => 'not_found' ]); } }