- 등록 폼: 중성화 여부(완료/안 함) 필수 토글, 미선택 시 등록 불가 - AI 추천: 중성화 찾기 옵션(상관없음/완료/안 함) → 조건 강아지 중에서만 추천 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+5
-2
@@ -40,8 +40,11 @@ export const spotsApi = {
|
|||||||
list: () => http.get<Spot[]>('/api/spots'),
|
list: () => http.get<Spot[]>('/api/spots'),
|
||||||
mates: (spotId: number, userId?: number) =>
|
mates: (spotId: number, userId?: number) =>
|
||||||
http.get<Mate[]>(`/api/spots/${spotId}/mates${userId ? `?userId=${userId}` : ''}`),
|
http.get<Mate[]>(`/api/spots/${spotId}/mates${userId ? `?userId=${userId}` : ''}`),
|
||||||
aiMates: (spotId: number, dogId: number) =>
|
aiMates: (spotId: number, dogId: number, neutered?: boolean) =>
|
||||||
http.get<AiMate[]>(`/api/spots/${spotId}/ai-mates?dogId=${dogId}`),
|
http.get<AiMate[]>(
|
||||||
|
`/api/spots/${spotId}/ai-mates?dogId=${dogId}` +
|
||||||
|
(neutered != null ? `&neutered=${neutered}` : ''),
|
||||||
|
),
|
||||||
frequentBreeds: (spotId: number) =>
|
frequentBreeds: (spotId: number) =>
|
||||||
http.get<{ breeds: string[] }>(`/api/spots/${spotId}/frequent-breeds`),
|
http.get<{ breeds: string[] }>(`/api/spots/${spotId}/frequent-breeds`),
|
||||||
reviews: (spotId: number) => http.get<Review[]>(`/api/spots/${spotId}/reviews`),
|
reviews: (spotId: number) => http.get<Review[]>(`/api/spots/${spotId}/reviews`),
|
||||||
|
|||||||
+23
-1
@@ -40,6 +40,26 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="text-caption text-grey-5 q-ml-xs">· AI 분석으로 실제와 다를 수 있어요</span>
|
<span class="text-caption text-grey-5 q-ml-xs">· AI 분석으로 실제와 다를 수 있어요</span>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 찾기 옵션: 중성화 조건 -->
|
||||||
|
<div class="row items-center q-mb-sm">
|
||||||
|
<span class="text-caption text-grey-7 q-mr-sm">중성화</span>
|
||||||
|
<q-btn-toggle
|
||||||
|
v-model="aiNeutered"
|
||||||
|
dense
|
||||||
|
unelevated
|
||||||
|
no-caps
|
||||||
|
size="sm"
|
||||||
|
toggle-color="primary"
|
||||||
|
color="grey-3"
|
||||||
|
text-color="grey-8"
|
||||||
|
:options="[
|
||||||
|
{ label: '상관없음', value: 'any' },
|
||||||
|
{ label: '완료', value: 'yes' },
|
||||||
|
{ label: '안 함', value: 'no' },
|
||||||
|
]"
|
||||||
|
@update:model-value="loadAiMates"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div v-if="aiLoading" class="row items-center q-gutter-sm text-grey-6">
|
<div v-if="aiLoading" class="row items-center q-gutter-sm text-grey-6">
|
||||||
<q-spinner-dots size="24px" color="primary" />
|
<q-spinner-dots size="24px" color="primary" />
|
||||||
<span class="text-caption">친구 찾는 중…</span>
|
<span class="text-caption">친구 찾는 중…</span>
|
||||||
@@ -153,6 +173,7 @@ const loadError = ref(false)
|
|||||||
const aiMates = ref<AiMate[]>([])
|
const aiMates = ref<AiMate[]>([])
|
||||||
const aiLoading = ref(false)
|
const aiLoading = ref(false)
|
||||||
const aiTried = ref(false)
|
const aiTried = ref(false)
|
||||||
|
const aiNeutered = ref<'any' | 'yes' | 'no'>('any') // AI 찾기 옵션: 중성화 조건
|
||||||
|
|
||||||
onMounted(load)
|
onMounted(load)
|
||||||
|
|
||||||
@@ -218,8 +239,9 @@ async function loadAiMates() {
|
|||||||
if (!currentSpot.value || dogs.currentDogId == null) return
|
if (!currentSpot.value || dogs.currentDogId == null) return
|
||||||
aiLoading.value = true
|
aiLoading.value = true
|
||||||
aiTried.value = true
|
aiTried.value = true
|
||||||
|
const neutered = aiNeutered.value === 'yes' ? true : aiNeutered.value === 'no' ? false : undefined
|
||||||
try {
|
try {
|
||||||
aiMates.value = await spotsApi.aiMates(currentSpot.value.id, dogs.currentDogId)
|
aiMates.value = await spotsApi.aiMates(currentSpot.value.id, dogs.currentDogId, neutered)
|
||||||
} catch {
|
} catch {
|
||||||
aiMates.value = []
|
aiMates.value = []
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -102,6 +102,22 @@
|
|||||||
emit-value
|
emit-value
|
||||||
map-options
|
map-options
|
||||||
/>
|
/>
|
||||||
|
<div>
|
||||||
|
<div class="text-caption text-grey-7 q-mb-xs">중성화 여부 <span class="text-negative">*</span></div>
|
||||||
|
<q-btn-toggle
|
||||||
|
v-model="form.neutered"
|
||||||
|
spread
|
||||||
|
unelevated
|
||||||
|
no-caps
|
||||||
|
toggle-color="primary"
|
||||||
|
color="grey-3"
|
||||||
|
text-color="grey-8"
|
||||||
|
:options="[
|
||||||
|
{ label: '중성화 완료', value: true },
|
||||||
|
{ label: '안 함', value: false },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right">
|
<q-card-actions align="right">
|
||||||
<q-btn flat label="취소" v-close-popup />
|
<q-btn flat label="취소" v-close-popup />
|
||||||
@@ -110,7 +126,7 @@
|
|||||||
unelevated
|
unelevated
|
||||||
label="등록"
|
label="등록"
|
||||||
:loading="creating"
|
:loading="creating"
|
||||||
:disable="!form.name"
|
:disable="!form.name || form.neutered === null"
|
||||||
@click="onCreate"
|
@click="onCreate"
|
||||||
/>
|
/>
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
@@ -141,10 +157,16 @@ const sizeOptions = [
|
|||||||
{ label: '중형견', value: 'MEDIUM' },
|
{ label: '중형견', value: 'MEDIUM' },
|
||||||
{ label: '대형견', value: 'LARGE' },
|
{ label: '대형견', value: 'LARGE' },
|
||||||
]
|
]
|
||||||
const form = reactive<{ name: string; breed: string; size: string | null }>({
|
const form = reactive<{
|
||||||
|
name: string
|
||||||
|
breed: string
|
||||||
|
size: string | null
|
||||||
|
neutered: boolean | null
|
||||||
|
}>({
|
||||||
name: '',
|
name: '',
|
||||||
breed: '',
|
breed: '',
|
||||||
size: null,
|
size: null,
|
||||||
|
neutered: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -208,13 +230,20 @@ function openCreate() {
|
|||||||
form.name = ''
|
form.name = ''
|
||||||
form.breed = ''
|
form.breed = ''
|
||||||
form.size = null
|
form.size = null
|
||||||
|
form.neutered = null
|
||||||
createOpen.value = true
|
createOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onCreate() {
|
async function onCreate() {
|
||||||
|
if (form.neutered === null) return
|
||||||
creating.value = true
|
creating.value = true
|
||||||
try {
|
try {
|
||||||
await dogs.createDog({ name: form.name, breed: form.breed || null, size: form.size })
|
await dogs.createDog({
|
||||||
|
name: form.name,
|
||||||
|
breed: form.breed || null,
|
||||||
|
size: form.size,
|
||||||
|
neutered: form.neutered,
|
||||||
|
})
|
||||||
createOpen.value = false
|
createOpen.value = false
|
||||||
$q.notify({ color: 'primary', message: `${form.name} 등록 완료!`, icon: 'pets', position: 'top' })
|
$q.notify({ color: 'primary', message: `${form.name} 등록 완료!`, icon: 'pets', position: 'top' })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user