request->getJSON(true); $itemType = isset($request['TYPE']) ? $request['TYPE'] : null; $showYn = isset($request['SHOW_YN']) ? $request['SHOW_YN'] : null; $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null; $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null; $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null; // 쿼리 빌더 $builder = $db->table('ITEM_LIST')->where('DEL_YN', 'N'); // 노출중, 비노출 여부 확인 if (!is_null($showYn) && $showYn !== '') { $builder->where('SHOW_YN', $showYn); } $builder->where('TYPE', $itemType); // 사용자 타입별 필터링 if ($memberType === 'VENDOR' && !empty($companyNumber)) { // 벤더사의 경우: 자사 제품만 조회 $builder->where('COMPANY_NUMBER', $companyNumber); } elseif ($memberType === 'INFLUENCER' && !empty($memberSeq)) { // 인플루언서의 경우: 파트너십이 체결된 벤더사의 제품만 조회 // VENDOR_INFLUENCER_PARTNERSHIP 테이블과 VENDOR_LIST를 통해 조인 $builder->select('ITEM_LIST.*, VIP.STATUS as PARTNERSHIP_STATUS'); $builder->join('VENDOR_LIST VL', 'ITEM_LIST.COMPANY_NUMBER = VL.COMPANY_NUMBER', 'inner'); $builder->join('VENDOR_INFLUENCER_PARTNERSHIP VIP', 'VL.SEQ = VIP.VENDOR_SEQ', 'inner'); $builder->where('VIP.INFLUENCER_SEQ', $memberSeq); $builder->where('VIP.STATUS', 'APPROVED'); $builder->where('VIP.IS_ACTIVE', 'Y'); } // 업데이트 날짜 기준으로 정렬 $builder->orderBy('ITEM_LIST.UDPDATE', 'DESC'); $lists = $builder->get()->getResultArray(); return $this->respond($lists, 200); } //아이템 검색 public function itemSearch() { $db = \Config\Database::connect(); // 요청 바디에서 filter와 keyword 추출 (예: {filter: "id", keyword: "admin"}) $request = $this->request->getJSON(true); $filter = isset($request['filter']) ? $request['filter'] : null; $keyword = isset($request['keyword']) ? $request['keyword'] : null; $startDate = $request['startDate'] ?? null; $endDate = $request['endDate'] ?? null; $showYN = $request['showYN'] ?? null; $itemType = isset($request['TYPE']) ? $request['TYPE'] : null; $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null; $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null; $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null; $filterMap = [ 'name' => 'NAME', ]; // 평문 검색 (LIKE 연산 사용) $builder = $db->table('ITEM_LIST'); // 사용자 타입별 필터링 if ($memberType === 'VENDOR' && !empty($companyNumber)) { // 벤더사의 경우: 자사 제품만 검색 $builder->where('COMPANY_NUMBER', $companyNumber); } elseif ($memberType === 'INFLUENCER' && !empty($memberSeq)) { // 인플루언서의 경우: 파트너십이 체결된 벤더사의 제품만 검색 $builder->select('ITEM_LIST.*, VIP.STATUS as PARTNERSHIP_STATUS'); $builder->join('VENDOR_LIST VL', 'ITEM_LIST.COMPANY_NUMBER = VL.COMPANY_NUMBER', 'inner'); $builder->join('VENDOR_INFLUENCER_PARTNERSHIP VIP', 'VL.SEQ = VIP.VENDOR_SEQ', 'inner'); $builder->where('VIP.INFLUENCER_SEQ', $memberSeq); $builder->where('VIP.STATUS', 'APPROVED'); $builder->where('VIP.IS_ACTIVE', 'Y'); } if (!empty($keyword)) { if (empty($filter)) { // 필터를 선택 안했으면 전체 검색 $first = true; foreach ($filterMap as $column) { if ($first) { $builder->like($column, $keyword); $first = false; } else { $builder->orLike($column, $keyword); } } } elseif (isset($filterMap[$filter])) { // 특정 필터 검색 $builder->like($filterMap[$filter], $keyword); } } // 인플루언서의 경우는 비노출 항목 가림 if (!empty($showYN)) { $builder->where('SHOW_YN', $showYN); } if (!empty($itemType)) { $builder->where('TYPE', $itemType); } // 정렬: UPDATE 기준 최신순 $builder->where('UDPDATE >=', $startDate . ' 00:00:00'); $builder->where('UDPDATE <=', $endDate . ' 23:59:59'); $builder->where('DEL_YN =', 'N'); $builder->orderBy('ITEM_LIST.UDPDATE', 'DESC'); // 조회 $lists = $builder->get()->getResultArray(); return $this->respond($lists, 200); } //아이템 등록 public function itemRegister() { $db = \Config\Database::connect(); $request = \Config\Services::request(); $regdate = date('Y-m-d H:i:s'); $thumb = $request->getFile('thumb_file'); $zip = $request->getFile('zip_file'); $zipOrigin = $zip ? $zip->getClientName() : null; // 기본 유효성 검사 if ( !$request->getPost('name') || !$request->getPost('price1') || !$request->getPost('price2') || !$request->getPost('deli_fee') || !$request->getPost('sub_title') || !$request->getPost('detail') || !$request->getPost('company_number') ) { return $this->respond([ 'status' => 'fail', 'message' => '필수 값이 누락됐습니다.' ], 400); } $db->transBegin(); // 트랜잭션 시작 try { // 썸네일 파일 처리 $thumbFileName = null; if ($thumb && $thumb->isValid() && !$thumb->hasMoved()) { $thumbFileName = $thumb->getRandomName(); // 랜덤파일명 생성 $thumb->move(WRITEPATH . 'uploads/item/thumb/', $thumbFileName); // 저장 } // 상세 zip 파일 처리 $zipFileName = null; if ($zip && $zip->isValid() && !$zip->hasMoved()) { $zipFileName = $zip->getRandomName(); $zip->move(WRITEPATH . 'uploads/item/detail/', $zipFileName); } // 1. ITEM_LIST에 아이템 정보 등록 $itemData = [ 'NAME' => $request->getPost('name'), 'PRICE1' => $request->getPost('price1'), 'PRICE2' => $request->getPost('price2'), 'DELI_FEE' => $request->getPost('deli_fee'), 'SUB_TITLE' => $request->getPost('sub_title'), 'DETAIL' => $request->getPost('detail'), 'STATUS' => $request->getPost('status'), 'SHOW_YN' => $request->getPost('show_yn'), 'ADD_INFO' => $request->getPost('add_info') ?? 0, 'CONTACT_INF' => $request->getPost('contact_inf') ?? 0, 'ORDER_LINK' => $request->getPost('order_link') ?? 0, 'ORDER_START_DATE' => $request->getPost('order_start_date') ?? 0, 'ORDER_END_DATE' => $request->getPost('order_end_date') ?? 0, 'COMPANY_NUMBER' => $request->getPost('company_number'), 'REGDATE' => $regdate, 'UDPDATE' => $regdate, 'TYPE' => $request->getPost('item_type'), 'THUMB_FILE' => $thumbFileName, // 파일명 저장 'ZIP_FILE' => $zipFileName, // 파일명 저장 'ZIP_FILE_ORIGIN' => $zipOrigin, // 원본 파일명 저장 ]; $insertResult = $db->table('ITEM_LIST')->insert($itemData); if (!$insertResult) { $error = $db->error(); return $this->respond([ 'status' => 'fail', 'message' => 'Insert 실패: ' . $error['message'] ], 500); } $itemSeq = $db->insertID(); // 생성된 이벤트 SEQ값 $db->transCommit(); return $this->respond([ 'status' => 'success', 'item_seq' => $itemSeq ], 201); } catch (\Exception $e) { $db->transRollback(); return $this->respond([ 'status' => 'fail', 'message' => 'DB 오류: ' . $e->getMessage() ], 500); } } //아이템 상세 public function itemDetail($seq) { // DB 객체 얻기 $db = \Config\Database::connect(); $builder = $db->table('ITEM_LIST'); $item = $builder->where('seq', $seq)->get()->getRowArray(); if($item){ return $this->respond($item, 200); } else { return $this->respond([ 'status' => 'fail', 'message' => '유효하지 않은 seq입니다.' ], 404); } } //상세 다운로드 public function file($fileName) { helper('filesystem'); $path = WRITEPATH . 'uploads/item/detail/' . $fileName; if (!file_exists($path)) { return $this->failNotFound('파일을 찾을 수 없습니다.'); } return $this->response ->download($path, null) ->setFileName($fileName); } //아이템 수정 public function ItemUpdate($seq) { $db = \Config\Database::connect(); $request = $this->request; $upddate = date('Y-m-d H:i:s'); $thumb = $request->getFile('thumb_file'); $zip = $request->getFile('zip_file'); // 기본 유효성 검사 if ( !$request->getPost('name') || !$request->getPost('price1') || !$request->getPost('price2') || !$request->getPost('deli_fee') || !$request->getPost('sub_title') || !$request->getPost('detail') || !$request->getPost('company_number') ) { return $this->respond([ 'status' => 'fail', 'message' => '필수 값이 누락됐습니다. ' ], 400); } $existingItem = $db->table('ITEM_LIST')->where('SEQ', $seq)->get()->getRow(); if (!$existingItem) { return $this->respond([ 'status' => 'fail', 'message' => '해당 아이템이 존재하지 않습니다.' ], 404); } // 파일명 유지 혹은 새 파일 저장 $thumbFileName = $existingItem->THUMB_FILE; if ($thumb && $thumb->isValid() && !$thumb->hasMoved()) { $thumbFileName = $thumb->getRandomName(); $thumb->move(WRITEPATH . 'uploads/item/thumb/', $thumbFileName); } $zipFileName = $existingItem->ZIP_FILE; $zipOrigin = $existingItem->ZIP_FILE_ORIGIN; if ($zip && $zip->isValid() && !$zip->hasMoved()) { $zipFileName = $zip->getRandomName(); $zipOrigin = $zip->getClientName(); $zip->move(WRITEPATH . 'uploads/item/detail/', $zipFileName); } // 업데이트 데이터 준비 $itemData = [ 'NAME' => $request->getPost('name'), 'PRICE1' => $request->getPost('price1'), 'PRICE2' => $request->getPost('price2'), 'DELI_FEE' => $request->getPost('deli_fee'), 'SUB_TITLE' => $request->getPost('sub_title'), 'DETAIL' => $request->getPost('detail'), 'STATUS' => $request->getPost('status'), 'SHOW_YN' => $request->getPost('show_yn'), 'ADD_INFO' => $request->getPost('add_info') ?? 0, 'COMPANY_NUMBER' => $request->getPost('company_number'), 'UDPDATE' => $upddate, 'THUMB_FILE' => $thumbFileName, 'ZIP_FILE' => $zipFileName, 'ZIP_FILE_ORIGIN' => $zipOrigin, ]; $db->transBegin(); try { $db->table('ITEM_LIST')->where('SEQ', $seq)->update($itemData); $db->transCommit(); return $this->respond([ 'status' => 'success' ], 200); } catch (\Exception $e) { $db->transRollback(); return $this->respond([ 'status' => 'fail', 'message' => 'DB 오류: ' . $e->getMessage() ], 500); } } //아이템 삭제 public function itemDelete($seq) { $db = \Config\Database::connect(); $db->transBegin(); //아이템 삭제 $deleted = $db->table('ITEM_LIST') ->where('SEQ', $seq) ->update(['DEL_YN' => 'Y']); if ($db->transStatus() === false || !$deleted) { $db->transRollback(); return $this->respond(['status' => 'fail', 'message' => '이벤트 삭제 중 오류가 발생했습니다.']); } $db->transCommit(); return $this->respond(['status' => 'success', 'message' => '이벤트가 삭제되었습니다.'], 200); } }