| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 |
- <?php
- namespace App\Controllers;
- use CodeIgniter\RESTful\ResourceController;
- class Winner extends ResourceController
- {
- //당첨자 리스트
- public function winnerlist()
- {
- $db = \Config\Database::connect();
- // POST JSON 파라미터 받기
- $request = $this->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'
- ]);
- }
- }
|