feat: 실시간 채팅 UI (STOMP 연동)

- ChatDialog: 히스토리 로드 + 실시간 송수신, 내 메시지 우측 정렬, 연결상태 표시
- lib/chatSocket: STOMP 클라이언트(브로커 ws, Bearer 인증, 자동 재연결)
- api/chat 히스토리, HomePage 스팟 채팅 버튼
- @stomp/stompjs 의존성 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sb
2026-07-11 09:18:23 +09:00
parent d2e5495619
commit 9e4d1aa2af
6 changed files with 251 additions and 11 deletions
+36 -10
View File
@@ -11,16 +11,39 @@
백엔드에 연결하지 못했습니다. (서버 실행 여부를 확인하세요)
</q-banner>
<!-- 체크인 -->
<q-btn
color="primary"
class="full-width q-py-sm"
unelevated
:loading="checkingIn"
:disable="!currentSpot"
icon="place"
:label="checkedIn ? '체크인 완료 · 여기 있어요!' : '나 지금 여기 도착!'"
@click="onCheckIn"
<!-- 체크인 + 채팅 -->
<div class="row q-col-gutter-sm">
<div class="col">
<q-btn
color="primary"
class="full-width q-py-sm"
unelevated
:loading="checkingIn"
:disable="!currentSpot"
icon="place"
:label="checkedIn ? '체크인 완료' : '나 지금 여기 도착!'"
@click="onCheckIn"
/>
</div>
<div class="col-auto">
<q-btn
color="accent"
class="full-height q-px-md"
outline
:disable="!currentSpot"
icon="chat"
label="채팅"
@click="chatOpen = true"
/>
</div>
</div>
<!-- 스팟 채팅 -->
<ChatDialog
v-if="currentSpot"
v-model="chatOpen"
:spot-id="currentSpot.id"
:spot-name="currentSpot.name"
/>
<!-- 스팟 한줄평 (네이버 지도식 태그형) -->
@@ -77,11 +100,14 @@ import { ApiError } from '@/api/http'
import { useAuthStore } from '@/stores/auth'
import { useDogsStore } from '@/stores/dogs'
import NaverMap from '@/components/NaverMap.vue'
import ChatDialog from '@/components/ChatDialog.vue'
const $q = useQuasar()
const auth = useAuthStore()
const dogs = useDogsStore()
const chatOpen = ref(false)
// 체크인/매칭 주체: 로그인 회원 + 대표 강아지
const currentUserId = () => auth.member?.id ?? 0