|
|
@@ -1,51 +1,116 @@
|
|
|
<template>
|
|
|
- <div class="admin--page-content">
|
|
|
- <div class="admin--form">
|
|
|
- <!-- 낚시지역 상세 -->
|
|
|
- <table class="admin--form--table">
|
|
|
- <colgroup>
|
|
|
- <col style="width: 120px;">
|
|
|
- <col>
|
|
|
- </colgroup>
|
|
|
- <tbody>
|
|
|
- <tr>
|
|
|
- <th><div>지역명</div></th>
|
|
|
- <td>{{ formData.name || "-" }}</td>
|
|
|
- </tr>
|
|
|
- <tr>
|
|
|
- <th><div>등록일</div></th>
|
|
|
- <td>{{ formatDateTime(formData.created_at) }}</td>
|
|
|
- </tr>
|
|
|
- <tr>
|
|
|
- <th><div>최근 수정</div></th>
|
|
|
- <td>{{ formatDateTime(formData.updated_at) }}</td>
|
|
|
- </tr>
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
-
|
|
|
- <!-- 버튼 영역 -->
|
|
|
- <div class="admin--form-actions">
|
|
|
- <button type="button" class="admin--btn" @click="goToList">
|
|
|
- ← 목록으로
|
|
|
- </button>
|
|
|
- <button type="button" class="admin--btn admin--btn-red-border ml--auto" @click="handleDelete">
|
|
|
- 삭제
|
|
|
- </button>
|
|
|
- <button type="button" class="admin--btn admin--btn-red" @click="goToEdit">
|
|
|
- 수정
|
|
|
- </button>
|
|
|
+ <div>
|
|
|
+ <div class="admin--page-content">
|
|
|
+ <div class="admin--form">
|
|
|
+ <!-- 낚시지역 상세 -->
|
|
|
+ <table class="admin--form--table">
|
|
|
+ <colgroup>
|
|
|
+ <col style="width: 120px;">
|
|
|
+ <col>
|
|
|
+ </colgroup>
|
|
|
+ <tbody>
|
|
|
+ <tr>
|
|
|
+ <th><div>지역명</div></th>
|
|
|
+ <td>{{ formData.name || "-" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <th><div>등록일</div></th>
|
|
|
+ <td>{{ formatDateTime(formData.created_at) }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <th><div>최근 수정</div></th>
|
|
|
+ <td>{{ formatDateTime(formData.updated_at) }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+
|
|
|
+ <!-- 버튼 영역 -->
|
|
|
+ <div class="admin--form-actions">
|
|
|
+ <button type="button" class="admin--btn" @click="goToList">
|
|
|
+ ← 목록으로
|
|
|
+ </button>
|
|
|
+ <button type="button" class="admin--btn admin--btn-red-border ml--auto" @click="handleDelete">
|
|
|
+ 삭제
|
|
|
+ </button>
|
|
|
+ <button type="button" class="admin--btn admin--btn-red" @click="goToEdit">
|
|
|
+ 수정
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 알림 모달 -->
|
|
|
+ <AdminAlertModal
|
|
|
+ v-if="alertModal.show"
|
|
|
+ :title="alertModal.title"
|
|
|
+ :message="alertModal.message"
|
|
|
+ :type="alertModal.type"
|
|
|
+ @confirm="handleAlertConfirm"
|
|
|
+ @cancel="handleAlertCancel"
|
|
|
+ @close="closeAlertModal"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="admin--page-content mt--20">
|
|
|
+ <div class="admin--sub--table--title">
|
|
|
+ <p>해당 지역의 낚시어선 / 낚시터</p>
|
|
|
+ <div class="sub--table--info">
|
|
|
+ <span>🎣 낚시터 {{ fishingCount }}</span>
|
|
|
+ <span>🚢 낚시어선 {{ onboardCount }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 해당 지역의 어선 / 낚시터 -->
|
|
|
+ <div class="admin--table-wrapper">
|
|
|
+ <table class="admin--table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th style="width: 80px;">번호</th>
|
|
|
+ <th style="width: 180px;">구분</th>
|
|
|
+ <th>이름</th>
|
|
|
+ <th>주소</th>
|
|
|
+ <th>상태</th>
|
|
|
+ <th style="width: 120px;">등록일</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-if="isPlacesLoading">
|
|
|
+ <td colspan="6" class="admin--table-loading">데이터를 불러오는 중...</td>
|
|
|
+ </tr>
|
|
|
+ <tr v-else-if="!places || places.length === 0">
|
|
|
+ <td colspan="6" class="admin--table-empty">해당 지역에 등록된 낚시어선/낚시터가 없습니다.</td>
|
|
|
+ </tr>
|
|
|
+ <tr
|
|
|
+ v-else
|
|
|
+ v-for="(p, index) in places"
|
|
|
+ :key="p.place_type + '-' + p.id"
|
|
|
+ class="admin--table-row-clickable"
|
|
|
+ @click="goToPlace(p)"
|
|
|
+ >
|
|
|
+ <td class="date">{{ (onboardCount + fishingCount) - index }}</td>
|
|
|
+ <td>
|
|
|
+ <span :class="['admin--badge', p.place_type === 'onboard' ? 'admin--badge-active' : 'admin--badge-html']">
|
|
|
+ {{ p.place_type === "onboard" ? "낚시어선" : "낚시터" }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="admin--table-title">{{ p.name }}</td>
|
|
|
+ <td>{{ p.address || "-" }}</td>
|
|
|
+ <td>
|
|
|
+ <span :class="['admin--badge', p.status_YN === 'Y' ? 'admin--badge-active' : 'admin--badge-ended']">
|
|
|
+ {{ p.status_YN === "Y" ? "사용중" : "미사용" }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="date">{{ formatDate(p.created_at) }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 알림 모달 -->
|
|
|
- <AdminAlertModal
|
|
|
- v-if="alertModal.show"
|
|
|
- :title="alertModal.title"
|
|
|
- :message="alertModal.message"
|
|
|
- :type="alertModal.type"
|
|
|
- @confirm="handleAlertConfirm"
|
|
|
- @cancel="handleAlertCancel"
|
|
|
- @close="closeAlertModal"
|
|
|
- />
|
|
|
+ <!-- 전체보기 버튼 -->
|
|
|
+ <div class="admin--form" v-if="(onboardCount + fishingCount) > places.length">
|
|
|
+ <div class="admin--form-actions">
|
|
|
+ <button type="button" class="txt--btn ml--auto" @click="goToPlacesAll">
|
|
|
+ {{ onboardCount + fishingCount }}건 전체보기 ->
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -72,6 +137,12 @@
|
|
|
updated_at: "",
|
|
|
});
|
|
|
|
|
|
+ // 해당 지역의 낚시어선 / 낚시터
|
|
|
+ const places = ref([]);
|
|
|
+ const onboardCount = ref(0);
|
|
|
+ const fishingCount = ref(0);
|
|
|
+ const isPlacesLoading = ref(false);
|
|
|
+
|
|
|
// 알림 모달
|
|
|
const alertModal = ref({
|
|
|
show: false,
|
|
|
@@ -113,6 +184,16 @@
|
|
|
|
|
|
// 삭제
|
|
|
const handleDelete = () => {
|
|
|
+ // 연결된 데이터 있으면 차단
|
|
|
+ const total = onboardCount.value + fishingCount.value;
|
|
|
+ if (total > 0) {
|
|
|
+ showAlert(
|
|
|
+ `해당 지역에 등록된 낚시어선/낚시터가 있어 삭제할 수 없습니다.\n(낚시어선 ${onboardCount.value} / 낚시터 ${fishingCount.value})\n\n먼저 연결된 어선/낚시터를 다른 지역으로 옮기거나 삭제해 주세요.`,
|
|
|
+ "삭제 불가"
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
showConfirm(
|
|
|
`'${formData.value.name}' 낚시지역을 삭제하시겠습니까?`,
|
|
|
async () => {
|
|
|
@@ -131,6 +212,26 @@
|
|
|
// 이동
|
|
|
const goToList = () => router.push("/site-manager/area/list");
|
|
|
const goToEdit = () => router.push(`/site-manager/area/edit/${areaId}`);
|
|
|
+ const goToPlace = (p) => {
|
|
|
+ if (p.place_type === "onboard") {
|
|
|
+ router.push(`/site-manager/onboard/detail/${p.id}`);
|
|
|
+ } else if (p.place_type === "fishing") {
|
|
|
+ router.push(`/site-manager/fishing/detail/${p.id}`);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const goToPlacesAll = () => router.push(`/site-manager/area/places/${areaId}`);
|
|
|
+
|
|
|
+ // 해당 지역의 낚시어선/낚시터 로드 (최근 등록순 8개 + 카운트)
|
|
|
+ const loadPlaces = async () => {
|
|
|
+ isPlacesLoading.value = true;
|
|
|
+ const { data, error } = await get(`/area/${areaId}/places`, { params: { limit: 8 } });
|
|
|
+ if (!error && data?.success && data?.data) {
|
|
|
+ places.value = data.data.items || [];
|
|
|
+ onboardCount.value = data.data.onboard_count || 0;
|
|
|
+ fishingCount.value = data.data.fishing_count || 0;
|
|
|
+ }
|
|
|
+ isPlacesLoading.value = false;
|
|
|
+ };
|
|
|
|
|
|
// 일시 포맷
|
|
|
const formatDateTime = (dateString) => {
|
|
|
@@ -146,7 +247,16 @@
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+ // 날짜만
|
|
|
+ const formatDate = (dateString) => {
|
|
|
+ if (!dateString) return "-";
|
|
|
+ const date = new Date(dateString.replace(" ", "T"));
|
|
|
+ if (isNaN(date.getTime())) return dateString;
|
|
|
+ return date.toLocaleDateString("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit" });
|
|
|
+ };
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
loadDetail();
|
|
|
+ loadPlaces();
|
|
|
});
|
|
|
</script>
|