requireAuth(); if ($auth instanceof ResponseInterface) { return $auth; } try { $page = (int) ($this->request->getGet('page') ?? 1); $perPage = (int) ($this->request->getGet('per_page') ?? 10); if ($page < 1) $page = 1; if ($perPage < 1) $perPage = 10; $offset = ($page - 1) * $perPage; $search = trim((string) $this->request->getGet('search')); $db = $this->getDB(); $builder = $db->table($this->table); // soft delete 제외 $builder->where('deleted_YN', 'N'); if ($search !== '') { $builder->like('name', $search); } $total = $builder->countAllResults(false); $items = $builder ->select('id, name, created_at, updated_at') ->orderBy('id', 'DESC') ->limit($perPage, $offset) ->get() ->getResult(); return $this->respondSuccess([ 'items' => $items, 'total' => $total, 'page' => $page, 'per_page' => $perPage, 'total_pages' => (int) ceil($total / $perPage), ]); } catch (\Exception $e) { log_message('error', 'FishingAreaController index error: ' . $e->getMessage()); return $this->respondError('목록 조회 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * 낚시지역 등록 * POST /api/area */ public function create() { $auth = $this->requireAuth(); if ($auth instanceof ResponseInterface) { return $auth; } try { $payload = $this->request->getJSON(true); if (!is_array($payload) || empty($payload)) { $payload = $this->request->getPost() ?? []; } $name = trim((string) ($payload['name'] ?? '')); // 지역명 검증: 1~20자, 필수 if ($name === '') { return $this->respondError('지역명을 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST); } if (mb_strlen($name) > 20) { return $this->respondError('지역명은 20자 이내로 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST); } $db = $this->getDB(); // 중복 검사 (soft delete 제외) $exists = $db->table($this->table) ->where('name', $name) ->where('deleted_YN', 'N') ->countAllResults(); if ($exists > 0) { return $this->respondError('이미 등록된 지역명입니다.', ResponseInterface::HTTP_CONFLICT); } $insertData = [ 'name' => $name, 'created_at' => date('Y-m-d H:i:s'), ]; if (!$db->table($this->table)->insert($insertData)) { return $this->respondError('등록에 실패했습니다.', ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } $newId = $db->insertID(); $row = $db->table($this->table)->where('id', $newId)->get()->getRow(); return $this->respondSuccess($row, '낚시지역이 등록되었습니다.', ResponseInterface::HTTP_CREATED); } catch (\Exception $e) { log_message('error', 'FishingAreaController create error: ' . $e->getMessage()); return $this->respondError('등록 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * 낚시지역 상세 조회 * GET /api/area/:id */ public function show($id = null) { $auth = $this->requireAuth(); if ($auth instanceof ResponseInterface) { return $auth; } if (empty($id)) { return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST); } try { $row = $this->getDB()->table($this->table) ->select('id, name, created_at, updated_at') ->where('id', (int) $id) ->where('deleted_YN', 'N') ->get() ->getRow(); if (!$row) { return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND); } return $this->respondSuccess($row); } catch (\Exception $e) { log_message('error', 'FishingAreaController show error: ' . $e->getMessage()); return $this->respondError('조회 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * 낚시지역 수정 * PUT /api/area/:id */ public function update($id = null) { $auth = $this->requireAuth(); if ($auth instanceof ResponseInterface) { return $auth; } if (empty($id)) { return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST); } try { $payload = $this->request->getJSON(true); if (!is_array($payload) || empty($payload)) { $payload = $this->request->getRawInput() ?? []; } $name = trim((string) ($payload['name'] ?? '')); // 지역명 검증 if ($name === '') { return $this->respondError('지역명을 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST); } if (mb_strlen($name) > 20) { return $this->respondError('지역명은 20자 이내로 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST); } $db = $this->getDB(); // 대상 행 존재 확인 $exists = $db->table($this->table) ->where('id', (int) $id) ->where('deleted_YN', 'N') ->countAllResults(); if ($exists === 0) { return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND); } // 중복 검사 (자기 자신 제외) $dupe = $db->table($this->table) ->where('name', $name) ->where('id !=', (int) $id) ->where('deleted_YN', 'N') ->countAllResults(); if ($dupe > 0) { return $this->respondError('이미 등록된 지역명입니다.', ResponseInterface::HTTP_CONFLICT); } $updateData = [ 'name' => $name, 'updated_at' => date('Y-m-d H:i:s'), ]; $db->table($this->table)->where('id', (int) $id)->update($updateData); $row = $db->table($this->table)->where('id', (int) $id)->get()->getRow(); return $this->respondSuccess($row, '낚시지역이 수정되었습니다.'); } catch (\Exception $e) { log_message('error', 'FishingAreaController update error: ' . $e->getMessage()); return $this->respondError('수정 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } /** * 낚시지역 삭제 (soft delete) * DELETE /api/area/:id */ public function delete($id = null) { $auth = $this->requireAuth(); if ($auth instanceof ResponseInterface) { return $auth; } if (empty($id)) { return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST); } try { $db = $this->getDB(); $exists = $db->table($this->table) ->where('id', (int) $id) ->where('deleted_YN', 'N') ->countAllResults(); if ($exists === 0) { return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND); } $db->table($this->table) ->where('id', (int) $id) ->update([ 'deleted_YN' => 'Y', 'updated_at' => date('Y-m-d H:i:s'), ]); return $this->respondSuccess(null, '낚시지역이 삭제되었습니다.'); } catch (\Exception $e) { log_message('error', 'FishingAreaController delete error: ' . $e->getMessage()); return $this->respondError('삭제 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } } }