noticeView.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <template>
  2. <main>
  3. <section class="">
  4. <div class="sub--container type4">
  5. <div class="view--wrap" v-if="!loading">
  6. <div class="view--title">
  7. <h3>{{ noticeData.title }}</h3>
  8. <div class="view--info">
  9. <p>{{ noticeData.name }}</p>
  10. <span class="bar"></span>
  11. <p>{{ noticeData.regdate }}</p>
  12. <span class="bar"></span>
  13. <p>조회수 : {{ noticeData.viewcnt }}</p>
  14. </div>
  15. </div>
  16. <div class="view--cont">
  17. <div v-html="noticeData.contents"></div>
  18. </div>
  19. <div class="btn--wrap">
  20. <NuxtLink to="/contact/notice">목록</NuxtLink>
  21. </div>
  22. <div class="link--wrap">
  23. <NuxtLink v-if="prevData && prevData.board_idx" :to="`/contact/noticeView?idx=${prevData.board_idx}`" class="link">
  24. <p>이전글</p>
  25. <h5>{{ prevData.title }}</h5>
  26. <span>{{ prevData.regdate || '-' }}</span>
  27. </NuxtLink>
  28. <div v-if="!prevData || !prevData.board_idx" class="link">
  29. <p>이전글</p>
  30. <h5>이전글이 없습니다.</h5>
  31. <span>-</span>
  32. </div>
  33. <NuxtLink v-if="nextData && nextData.board_idx" :to="`/contact/noticeView?idx=${nextData.board_idx}`" class="link">
  34. <p>다음글</p>
  35. <h5>{{ nextData.title }}</h5>
  36. <span>{{ nextData.regdate || '-' }}</span>
  37. </NuxtLink>
  38. <div v-if="!nextData || !nextData.board_idx" class="link">
  39. <p>다음글</p>
  40. <h5>다음글이 없습니다.</h5>
  41. <span>-</span>
  42. </div>
  43. </div>
  44. </div>
  45. <div v-else class="loading">
  46. <p>로딩 중...</p>
  47. </div>
  48. </div>
  49. </section>
  50. </main>
  51. </template>
  52. <script setup>
  53. import { ref, onMounted, onUnmounted, watch } from 'vue'
  54. const route = useRoute()
  55. const idx = route.query.idx
  56. console.log("현재 라우트:", route)
  57. console.log("받은 idx:", idx)
  58. const loading = ref(true)
  59. const noticeData = ref({
  60. title: '',
  61. name: '',
  62. regdate: '',
  63. viewcnt: 0,
  64. contents: ''
  65. })
  66. const nextData = ref(null)
  67. const prevData = ref(null)
  68. let scrollObserver = null
  69. // 공지사항 상세 데이터 가져오기
  70. const fetchNoticeDetail = async () => {
  71. try {
  72. loading.value = true
  73. const currentIdx = route.query.idx
  74. if (!currentIdx) {
  75. throw new Error('게시글 ID가 없습니다.')
  76. }
  77. // POST 방식으로 파라미터 전달 (수정됨 - 2025-01-17)
  78. console.log('POST 요청 전송 중:', {boardId: 'notice', boardIdx: currentIdx})
  79. const response = await $postForm('/board_view', {
  80. boardId: 'notice',
  81. boardIdx: currentIdx
  82. })
  83. console.log("받은 상세 데이터:", response)
  84. if (response && response.success && response.view) {
  85. noticeData.value = {
  86. title: response.view.title || '',
  87. name: response.view.name || '그린웨일글로벌(주)',
  88. regdate: response.view.regdate || '',
  89. viewcnt: response.view.viewcnt || 0,
  90. contents: response.view.contents || ''
  91. }
  92. // 이전글/다음글 데이터
  93. nextData.value = response.next
  94. prevData.value = response.prev
  95. console.log("nextData:", nextData.value)
  96. console.log("prevData:", prevData.value)
  97. } else {
  98. throw new Error('게시글을 찾을 수 없습니다.')
  99. }
  100. } catch (error) {
  101. console.error('공지사항 상세 데이터 로드 실패:', error)
  102. alert('게시글을 불러올 수 없습니다.')
  103. navigateTo('/contact/notice')
  104. } finally {
  105. loading.value = false
  106. }
  107. }
  108. // URL 파라미터 변경 감지를 위한 watcher 추가
  109. watch(() => route.query.idx, (newIdx) => {
  110. if (newIdx) {
  111. fetchNoticeDetail()
  112. }
  113. })
  114. onMounted(() => {
  115. // 데이터 로드
  116. fetchNoticeDetail()
  117. // 헤더 스타일 처리
  118. const header = document.querySelector('.header--wrap')
  119. if (header) {
  120. header.classList.add('white')
  121. // MutationObserver로 클래스 변경 감지 및 방지
  122. scrollObserver = new MutationObserver((mutations) => {
  123. mutations.forEach((mutation) => {
  124. if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
  125. if (!header.classList.contains('white')) {
  126. header.classList.add('white')
  127. }
  128. }
  129. })
  130. })
  131. scrollObserver.observe(header, {
  132. attributes: true,
  133. attributeFilter: ['class']
  134. })
  135. }
  136. })
  137. onUnmounted(() => {
  138. const header = document.querySelector('.header--wrap')
  139. if (header) {
  140. header.classList.remove('white')
  141. }
  142. if (scrollObserver) {
  143. scrollObserver.disconnect()
  144. }
  145. })
  146. </script>