
--- client/resources/api/dcry.js
+++ client/resources/api/dcry.js
... | ... | @@ -1,8 +1,8 @@ |
1 | 1 |
import { apiClient, fileClient } from "./index"; |
2 | 2 |
|
3 | 3 |
// 기록물 목록 조회 |
4 |
-export const findAllDatas = (searchReqDTO) => { |
|
5 |
- return apiClient.get(`/dcry/findAllDatas.json`, { params: searchReqDTO }); |
|
4 |
+export const findDcrysProc = (searchReqDTO) => { |
|
5 |
+ return apiClient.get(`/dcry/findDcrys.json`, { params: searchReqDTO }); |
|
6 | 6 |
} |
7 | 7 |
|
8 | 8 |
// 기록물 상세 조회 |
--- client/resources/js/cmmnPlugin.js
+++ client/resources/js/cmmnPlugin.js
... | ... | @@ -22,5 +22,10 @@ |
22 | 22 |
const dateOnly = dateString.split(' ')[0]; |
23 | 23 |
return dateOnly.replace(/-/g, '.'); |
24 | 24 |
} |
25 |
+ |
|
26 |
+ // 정규식을 사용하여 모든 HTML 태그 제거 |
|
27 |
+ Vue.config.globalProperties.$stripHtml = (html) => { |
|
28 |
+ return html.replace(/<[^>]*>/g, ''); |
|
29 |
+ } |
|
25 | 30 |
} |
26 | 31 |
}(파일 끝에 줄바꿈 문자 없음) |
--- client/views/component/List/CardViewList.vue
+++ client/views/component/CardViewList.vue
... | ... | @@ -10,8 +10,8 @@ |
10 | 10 |
<ul> |
11 | 11 |
<li v-for="(item, idx2) of list" :key="idx2" class="result-box mb-15"> |
12 | 12 |
<div class="main-img"> |
13 |
- <img v-if="item.hasOwnProperty('files') && item.files.length > 0" :src="item.files[0].filePath" alt=""> |
|
14 |
- <img v-else src="client/resources/images/img6.png" alt=""> |
|
13 |
+ <img v-if="item.hasOwnProperty('files') && item.files.length > 0" :src="item.files[0].filePath" :alt="item.sj + ' 첫 번째 이미지'"> |
|
14 |
+ <img v-else src="client/resources/images/img6.png" alt="Not found image"> |
|
15 | 15 |
</div> |
16 | 16 |
<div class="text-box"> |
17 | 17 |
<h5>{{ item.sj }}</h5> |
+++ client/views/component/DefaultPagination.vue
... | ... | @@ -0,0 +1,44 @@ |
1 | +<template> | |
2 | + <div class="pagination flex-center"> | |
3 | + <button type="button" :disabled="search.currentPage === search.startPage" @click="$emit('onChange', search.startPage)"> | |
4 | + <DoubleLeftOutlined /> | |
5 | + </button> | |
6 | + <button type="button" :disabled="!search.existPrevPage" @click="$emit('onChange', (search.currentPage - 1))"> | |
7 | + <LeftOutlined /> | |
8 | + </button> | |
9 | + <template v-for="idx in search.totalPageCount" :key="idx"> | |
10 | + <button type="button" :class="{ 'page-number': true, clicked: search.currentPage === idx }" :disabled="search.currentPage === idx" @click="$emit('onChange', idx)">{{ idx }}</button> | |
11 | + </template> | |
12 | + <button type="button" :disabled="!search.existNextPage" @click="$emit('onChange', (search.currentPage + 1))"> | |
13 | + <RightOutlined /> | |
14 | + </button> | |
15 | + <button type="button" :disabled="search.currentPage === search.endPage" @click="$emit('onChange', search.endPage)"> | |
16 | + <DoubleRightOutlined /> | |
17 | + </button> | |
18 | + </div> | |
19 | +</template> | |
20 | +<script> | |
21 | +import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; | |
22 | +export default { | |
23 | + components: { | |
24 | + DoubleLeftOutlined, | |
25 | + LeftOutlined, | |
26 | + RightOutlined, | |
27 | + DoubleRightOutlined, | |
28 | + }, | |
29 | + | |
30 | + props: { | |
31 | + search: { | |
32 | + type: Object, | |
33 | + default: {}, | |
34 | + } | |
35 | + }, | |
36 | + | |
37 | + methods: {}, | |
38 | +} | |
39 | +</script> | |
40 | +<style scoped> | |
41 | +button:disabled { | |
42 | + cursor: not-allowed; | |
43 | +} | |
44 | +</style>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/component/EditorComponent.vue
+++ client/views/component/editor/EditorComponent.vue
No changes |
--- client/views/component/ViewerComponent.vue
+++ client/views/component/editor/ViewerComponent.vue
No changes |
+++ client/views/component/listLayout/CardStyleComponent.vue
... | ... | @@ -0,0 +1,82 @@ |
1 | +<template> | |
2 | + <ul class="card-wrap"> | |
3 | + <li v-for="(item, idx) in list" :key="idx" class="mb-30" @click="fnMoveTo(item)"> | |
4 | + <div class="result-box"> | |
5 | + <div class="main-img"> | |
6 | + <img v-if="item.hasOwnProperty('files') && item.files.length > 0" :src="item.files[0].filePath" :alt="item.sj + ' 첫 번째 이미지'"> | |
7 | + <img v-else src="client/resources/images/img6.png" alt="Not found image"> | |
8 | + </div> | |
9 | + <div class="text-box"> | |
10 | + <router-link :to="{ path: '/PicHistoryDetail.page' }"> | |
11 | + <h5>{{ item.sj }}</h5> | |
12 | + </router-link> | |
13 | + <p v-if="item.hasOwnProperty('adres')" class="address">{{ item.adres }}</p> | |
14 | + <p class="text">{{ $stripHtml(item.cn) }}</p> | |
15 | + <div class="mb-20"> | |
16 | + <ul class="category"> | |
17 | + <li v-for="(ctgry, ctgryIdx) of item.ctgrys" :key="ctgryIdx" class="category1">{{ ctgry.ctgryNm }}</li> | |
18 | + </ul> | |
19 | + </div> | |
20 | + <div class="date"> | |
21 | + <ul> | |
22 | + <li>생산연도 <b>{{ item.prdctnYear ? item.prdctnYear : '-' }}</b></li> | |
23 | + <li>|</li> | |
24 | + <li>등록 <b>{{ item.rgsde }}</b></li> | |
25 | + </ul> | |
26 | + </div> | |
27 | + </div> | |
28 | + </div> | |
29 | + </li> | |
30 | + </ul> | |
31 | +</template> | |
32 | +<script> | |
33 | +export default { | |
34 | + name: "CardStyleComponent", | |
35 | + | |
36 | + props: { | |
37 | + name: { | |
38 | + type: String, | |
39 | + default: 'P', | |
40 | + }, | |
41 | + list: { | |
42 | + type: Array, | |
43 | + default: () => [], | |
44 | + }, | |
45 | + }, | |
46 | + | |
47 | + computed: { | |
48 | + page() { | |
49 | + switch (this.name) { | |
50 | + case 'P': | |
51 | + return 'PicHistoryDetail'; | |
52 | + case 'V': | |
53 | + return 'VideoHistoryDetail'; | |
54 | + case 'M': | |
55 | + return 'MediaVideoDetail'; | |
56 | + case 'N': | |
57 | + return 'NewsReleaseDetail'; | |
58 | + } | |
59 | + }, | |
60 | + }, | |
61 | + | |
62 | + methods: { | |
63 | + // 페이지 이동 | |
64 | + fnMoveTo(item) { | |
65 | + let key = null; | |
66 | + switch (this.name) { | |
67 | + case 'P': | |
68 | + case 'V': | |
69 | + key = 'dcryId'; | |
70 | + break; | |
71 | + case 'M': | |
72 | + key = 'mediaVidoId'; | |
73 | + break; | |
74 | + case 'N': | |
75 | + key = 'nesDtaId'; | |
76 | + break; | |
77 | + } | |
78 | + this.$router.push({ name: this.page, query: { id: item[key] } }); | |
79 | + } | |
80 | + }, | |
81 | +}; | |
82 | +</script>(파일 끝에 줄바꿈 문자 없음) |
+++ client/views/component/listLayout/ListStyleComponent.vue
... | ... | @@ -0,0 +1,75 @@ |
1 | +<template> | |
2 | + <ul class="list-wrap"> | |
3 | + <li v-for="(item, idx) in list" :key="idx" class="mb-30" @click="fnMoveTo(item)"> | |
4 | + <div class="text-box"> | |
5 | + <h5>{{ item.sj }}</h5> | |
6 | + <p v-if="item.hasOwnProperty('adres')" class="address">{{ item.adres }}</p> | |
7 | + <div class="flex-sp-bw"> | |
8 | + <div class="mb-20"> | |
9 | + <ul class="category"> | |
10 | + <li v-for="(ctgry, idx3) of item.ctgrys" :key="idx3" class="category1">{{ ctgry.ctgryNm }}</li> | |
11 | + </ul> | |
12 | + </div> | |
13 | + <div class="date "> | |
14 | + <ul> | |
15 | + <li>생산연도 <b>{{ item.prdctnYear ? item.prdctnYear : '-' }}</b></li> | |
16 | + <li>|</li> | |
17 | + <li>등록 <b>{{ item.rgsde }}</b></li> | |
18 | + </ul> | |
19 | + </div> | |
20 | + </div> | |
21 | + </div> | |
22 | + </li> | |
23 | + </ul> | |
24 | +</template> | |
25 | +<script> | |
26 | +export default { | |
27 | + name: "ListStyleComponent", | |
28 | + | |
29 | + props: { | |
30 | + name: { | |
31 | + type: String, | |
32 | + default: 'P', | |
33 | + }, | |
34 | + list: { | |
35 | + type: Array, | |
36 | + default: () => [], | |
37 | + }, | |
38 | + }, | |
39 | + | |
40 | + computed: { | |
41 | + page() { | |
42 | + switch (this.name) { | |
43 | + case 'P': | |
44 | + return 'PicHistoryDetail'; | |
45 | + case 'V': | |
46 | + return 'VideoHistoryDetail'; | |
47 | + case 'M': | |
48 | + return 'MediaVideoDetail'; | |
49 | + case 'N': | |
50 | + return 'NewsReleaseDetail'; | |
51 | + } | |
52 | + }, | |
53 | + }, | |
54 | + | |
55 | + methods: { | |
56 | + // 페이지 이동 | |
57 | + fnMoveTo(item) { | |
58 | + let key = null; | |
59 | + switch (this.name) { | |
60 | + case 'P': | |
61 | + case 'V': | |
62 | + key = 'dcryId'; | |
63 | + break; | |
64 | + case 'M': | |
65 | + key = 'mediaVidoId'; | |
66 | + break; | |
67 | + case 'N': | |
68 | + key = 'nesDtaId'; | |
69 | + break; | |
70 | + } | |
71 | + this.$router.push({ name: this.page, query: { id: item[key] } }); | |
72 | + } | |
73 | + }, | |
74 | +}; | |
75 | +</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/component/modal/CategorySelectModal.vue
+++ client/views/component/modal/CategorySelectModal.vue
... | ... | @@ -1,9 +1,9 @@ |
1 | 1 |
<template> |
2 |
- <div class="modal-overlay" @click="closeModal"> |
|
2 |
+ <div class="modal-overlay"> |
|
3 | 3 |
<div class="modal-content" @click.stop> |
4 | 4 |
<div class="flex-sp-bw mb-20"> |
5 | 5 |
<h2>카테고리 조회</h2> |
6 |
- <button @click="closeModal" class="closebtn">✕</button> |
|
6 |
+ <button class="closebtn" @click="$emit('toggleModal')">✕</button> |
|
7 | 7 |
</div> |
8 | 8 |
<div class="modal-search flex-center mb-20"> |
9 | 9 |
<input type="text" placeholder="카테고리명을 입력하세요." v-model="searchReqDTO.searchText" @keyup.enter="fnFindAllCategory"> |
... | ... | @@ -32,27 +32,13 @@ |
32 | 32 |
</tbody> |
33 | 33 |
</table> |
34 | 34 |
<div class="flex-end mb-30"><button class="register-b" @click="fnAddCtgries">등록</button></div> |
35 |
- <div class="pagination"> |
|
36 |
- <!-- Previous and Next Page Buttons --> |
|
37 |
- <button> |
|
38 |
- <DoubleLeftOutlined /> |
|
39 |
- </button> |
|
40 |
- <button @click="previousPage" :disabled="searchReqDTO.currentPage === 1"> |
|
41 |
- <LeftOutlined /> |
|
42 |
- </button> |
|
43 |
- <button class="page-number clicked">1</button> |
|
44 |
- <button @click="nextPage" :disabled="searchReqDTO.currentPage === searchReqDTO.recordSize"> |
|
45 |
- <RightOutlined /> |
|
46 |
- </button> |
|
47 |
- <button> |
|
48 |
- <DoubleRightOutlined /> |
|
49 |
- </button> |
|
50 |
- </div> |
|
35 |
+ <DefaultPagination :search="searchReqDTO" @onChange="fnChangeCurrentPage" /> |
|
51 | 36 |
</div> |
52 | 37 |
</div> |
53 | 38 |
</template> |
54 | 39 |
<script> |
55 |
-import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
|
40 |
+// COMPONENT |
|
41 |
+import DefaultPagination from '@/views/component/DefaultPagination.vue'; |
|
56 | 42 |
// API |
57 | 43 |
import { findAllCategoryProc } from '@/resources/api/category'; |
58 | 44 |
|
... | ... | @@ -60,10 +46,7 @@ |
60 | 46 |
name: 'CategorySelectModal', |
61 | 47 |
|
62 | 48 |
components: { |
63 |
- DoubleLeftOutlined, |
|
64 |
- LeftOutlined, |
|
65 |
- RightOutlined, |
|
66 |
- DoubleRightOutlined |
|
49 |
+ DefaultPagination |
|
67 | 50 |
}, |
68 | 51 |
|
69 | 52 |
props: { |
... | ... | @@ -80,20 +63,13 @@ |
80 | 63 |
|
81 | 64 |
// 검색 객체 |
82 | 65 |
searchReqDTO: { |
83 |
- currentPage: 1, |
|
84 |
- recordSize: 10, |
|
85 |
- pageSize: 10, |
|
86 |
- totalRecordCount: 5, |
|
87 |
- totalPageCount: 1, |
|
88 |
- startPage: 1, |
|
89 |
- endPage: 1, |
|
90 |
- limitStart: 0, |
|
91 |
- existPrevPage: false, |
|
92 |
- existNextPage: false, |
|
93 | 66 |
searchType: 'nm', |
94 | 67 |
searchText: null, |
95 | 68 |
useAt: 'Y', |
96 | 69 |
selectedCtgryIds: null, |
70 |
+ // 페이지네이션 |
|
71 |
+ currentPage: 1, // 현재 페이지 |
|
72 |
+ recordSize: 10, // 한 페이지에 표시할 데이터 개수 |
|
97 | 73 |
}, |
98 | 74 |
|
99 | 75 |
list: [], // 카테고리 목록 |
... | ... | @@ -112,11 +88,8 @@ |
112 | 88 |
if (this.selectedCtgries.length > 0) { |
113 | 89 |
this.searchReqDTO.selectedCtgryIds = this.selectedCtgries.map(item => item.ctgryId).join(','); |
114 | 90 |
} |
115 |
- console.log('req: ', this.searchReqDTO); |
|
116 | 91 |
|
117 | 92 |
const response = await findAllCategoryProc(this.searchReqDTO); |
118 |
- console.log('res: ', response.data.data.ctgry); |
|
119 |
- |
|
120 | 93 |
let ctgries = response.data.data.ctgry; |
121 | 94 |
for (let item of ctgries) { |
122 | 95 |
item.isSelected = false; |
... | ... | @@ -129,6 +102,7 @@ |
129 | 102 |
} |
130 | 103 |
|
131 | 104 |
this.list = ctgries; |
105 |
+ this.searchReqDTO = response.data.data.search; |
|
132 | 106 |
} catch (error) { |
133 | 107 |
alert('조회중 오류가 발생했습니다.'); |
134 | 108 |
|
... | ... | @@ -139,25 +113,19 @@ |
139 | 113 |
} |
140 | 114 |
}, |
141 | 115 |
|
142 |
- closeModal() { |
|
143 |
- this.$emit('toggleModal'); |
|
144 |
- }, |
|
145 |
- |
|
116 |
+ // 카테고리 추가 |
|
146 | 117 |
fnAddCtgries() { |
147 | 118 |
this.$emit('addCtgries', this.selectedList); |
148 | 119 |
}, |
149 | 120 |
|
150 |
- previousPage() { |
|
151 |
- if (this.searchReqDTO.currentPage > 1) { |
|
152 |
- this.searchReqDTO.currentPage--; |
|
153 |
- } |
|
154 |
- }, |
|
121 |
+ // 페이지 이동 |
|
122 |
+ fnChangeCurrentPage(currentPage) { |
|
123 |
+ this.searchReqDTO.currentPage = Number(currentPage); |
|
155 | 124 |
|
156 |
- nextPage() { |
|
157 |
- if (this.searchReqDTO.currentPage < this.searchReqDTO.recordSize) { |
|
158 |
- this.searchReqDTO.currentPage++; |
|
159 |
- } |
|
160 |
- } |
|
125 |
+ this.$nextTick(() => { |
|
126 |
+ this.fnFindAllCategory(); |
|
127 |
+ }); |
|
128 |
+ }, |
|
161 | 129 |
} |
162 | 130 |
}; |
163 | 131 |
</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/user/MediaVideoInsert.vue
+++ client/views/pages/user/MediaVideoInsert.vue
... | ... | @@ -57,7 +57,7 @@ |
57 | 57 |
<script> |
58 | 58 |
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
59 | 59 |
// COMPONENT |
60 |
-import EditorComponent from '../../component/EditorComponent.vue'; |
|
60 |
+import EditorComponent from '../../component/editor/EditorComponent.vue'; |
|
61 | 61 |
import CategorySelectModal from '../../component/modal/CategorySelectModal.vue'; |
62 | 62 |
|
63 | 63 |
export default { |
--- client/views/pages/user/NewsReleaseInsert.vue
+++ client/views/pages/user/NewsReleaseInsert.vue
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 |
<script> |
89 | 89 |
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
90 | 90 |
// COMPONENT |
91 |
-import EditorComponent from '../../component/EditorComponent.vue'; |
|
91 |
+import EditorComponent from '../../component/editor/EditorComponent.vue'; |
|
92 | 92 |
import CategorySelectModal from '../../component/modal/CategorySelectModal.vue'; |
93 | 93 |
|
94 | 94 |
export default { |
--- client/views/pages/user/PicHistoryDetail.vue
+++ client/views/pages/user/PicHistoryDetail.vue
... | ... | @@ -96,7 +96,7 @@ |
96 | 96 |
// import required modules |
97 | 97 |
import { FreeMode, Navigation, Thumbs } from 'swiper/modules'; |
98 | 98 |
// COMPONENT |
99 |
-import ViewerComponent from '../../component/ViewerComponent.vue'; |
|
99 |
+import ViewerComponent from '../../component/editor/ViewerComponent.vue'; |
|
100 | 100 |
// API |
101 | 101 |
import { findDcryProc, deleteDcryProc } from '@/resources/api/dcry'; |
102 | 102 |
import { fileDownloadProc, multiFileDownloadProc } from '@/resources/api/file'; |
... | ... | @@ -109,6 +109,7 @@ |
109 | 109 |
SwiperSlide, |
110 | 110 |
ViewerComponent, |
111 | 111 |
}, |
112 |
+ |
|
112 | 113 |
setup() { |
113 | 114 |
const thumbsSwiper = ref(null); |
114 | 115 |
|
... | ... | @@ -122,6 +123,7 @@ |
122 | 123 |
modules: [FreeMode, Navigation, Thumbs], |
123 | 124 |
}; |
124 | 125 |
}, |
126 |
+ |
|
125 | 127 |
data() { |
126 | 128 |
return { |
127 | 129 |
// ICON |
... | ... | @@ -138,19 +140,19 @@ |
138 | 140 |
selectedFiles: [], |
139 | 141 |
}; |
140 | 142 |
}, |
141 |
- methods: {}, |
|
142 |
- watch: {}, |
|
143 |
- computed: {}, |
|
143 |
+ |
|
144 | 144 |
created() { |
145 | 145 |
this.pageId = this.$route.query.id; |
146 | 146 |
if (this.pageId === null) { |
147 | 147 |
alert("게시물 존재하지 않습니다."); |
148 |
- return; |
|
148 |
+ this.fnMoveTo('PicHistorySearch'); |
|
149 | 149 |
} |
150 |
+ }, |
|
150 | 151 |
|
152 |
+ mounted() { |
|
151 | 153 |
this.fnFindDcry(); // 상세 조회 |
152 | 154 |
}, |
153 |
- mounted() { }, |
|
155 |
+ |
|
154 | 156 |
methods: { |
155 | 157 |
// 상세 조회 |
156 | 158 |
async fnFindDcry() { |
--- client/views/pages/user/PicHistoryInsert.vue
+++ client/views/pages/user/PicHistoryInsert.vue
... | ... | @@ -99,7 +99,7 @@ |
99 | 99 |
<script> |
100 | 100 |
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
101 | 101 |
// COMPONENT |
102 |
-import EditorComponent from '../../component/EditorComponent.vue'; |
|
102 |
+import EditorComponent from '../../component/editor/EditorComponent.vue'; |
|
103 | 103 |
import CategorySelectModal from '../../component/modal/CategorySelectModal.vue'; |
104 | 104 |
// API |
105 | 105 |
import { findDcryProc, saveDcry, updateDcry } from '@/resources/api/dcry'; |
... | ... | @@ -148,13 +148,16 @@ |
148 | 148 |
}; |
149 | 149 |
}, |
150 | 150 |
|
151 |
- computed: {}, |
|
152 |
- |
|
153 | 151 |
created() { |
154 | 152 |
this.pageId = this.$route.query.id; |
155 |
- if (!this.$isEmpty(this.pageId)) { |
|
156 |
- this.fnFindDcry(); // 상세 조회 |
|
153 |
+ if (this.pageId === null) { |
|
154 |
+ alert("게시물 존재하지 않습니다."); |
|
155 |
+ this.fnMoveTo('PicHistorySearch'); |
|
157 | 156 |
} |
157 |
+ }, |
|
158 |
+ |
|
159 |
+ mounted() { |
|
160 |
+ this.fnFindDcry(); // 상세 조회 |
|
158 | 161 |
}, |
159 | 162 |
|
160 | 163 |
methods: { |
... | ... | @@ -269,7 +272,7 @@ |
269 | 272 |
alert("제목을 입력해 주세요."); |
270 | 273 |
return; |
271 | 274 |
} |
272 |
- if (this.$isEmpty(this.pageId) && this.multipartFiles.length < 1) { |
|
275 |
+ if (this.$isEmpty(this.pageId) && this.multipartFiles.length == 0) { |
|
273 | 276 |
alert("파일을 1개 이상 첨부해 주세요."); |
274 | 277 |
return; |
275 | 278 |
} |
--- client/views/pages/user/PicHistorySearch.vue
+++ client/views/pages/user/PicHistorySearch.vue
... | ... | @@ -1,412 +1,296 @@ |
1 | 1 |
<template> |
2 |
- <div class="content"> |
|
3 |
- <div class="sub-title-area mb-30"> |
|
4 |
- <h2>사진 기록물</h2> |
|
5 |
- <div class="breadcrumb-list"> |
|
6 |
- <ul> |
|
7 |
- <!-- Bind the image source dynamically for homeicon --> |
|
8 |
- <li><img :src="homeicon" alt="Home Icon"> |
|
9 |
- <p>기록물</p> |
|
10 |
- </li> |
|
11 |
- <li><img :src="righticon" alt=""></li> |
|
12 |
- <li>사진 기록물</li> |
|
13 |
- </ul> |
|
14 |
- </div> |
|
15 |
- </div> |
|
16 |
- <div action="search" class="search-form form "> |
|
17 |
- <dl> |
|
18 |
- <dd class="mb-15"> |
|
19 |
- <p>검색범위</p> |
|
20 |
- <ul> |
|
21 |
- <li> |
|
22 |
- <input type="checkbox" id="allScope" v-model="isChkAllScope" |
|
23 |
- @change="fnChkAllOptions('scope')" /> |
|
24 |
- <label for="allScope">전체</label> |
|
25 |
- </li> |
|
26 |
- <li v-for="(scope, idx) in searchType" :key="idx"> |
|
27 |
- <input type="checkbox" :id="idx" :name="searchType" :value="scope.key" |
|
28 |
- v-model="searchReqDTO.searchType" @change="fnChkOption('scope')" /> |
|
29 |
- <label :for="idx">{{ scope.value }}</label> |
|
30 |
- </li> |
|
31 |
- </ul> |
|
32 |
- </dd> |
|
33 |
- <dd class="mb-15"> |
|
34 |
- <p>검색어</p> |
|
35 |
- <div class="wfull"><input type="text" v-model="searchReqDTO.searchText"></div> |
|
36 |
- </dd> |
|
37 |
- <dd class="mb-15"> |
|
38 |
- <p>생산연도</p> |
|
39 |
- <input type="date" v-model="searchReqDTO.startYear"> |
|
40 |
- <p class="mark">~</p> |
|
41 |
- <input type="date" v-model="searchReqDTO.endYear"> |
|
42 |
- </dd> |
|
43 |
- <dd class="mb-20"> |
|
44 |
- <p>카테고리</p> |
|
45 |
- <ul> |
|
46 |
- <li v-for="(category, idx) of categorys" :key="idx"> |
|
47 |
- <input type="checkbox" :id="category.ctgryId" name="categorys" :value="category.ctgryId" |
|
48 |
- v-model="searchReqDTO.searchCtgry" /> |
|
49 |
- <label :for="category.ctgryId">{{ category.ctgryNm }}</label> |
|
50 |
- </li> |
|
51 |
- </ul> |
|
52 |
- </dd> |
|
53 |
- <dd class="mb-15"> |
|
54 |
- <p>정렬</p> |
|
55 |
- <ul> |
|
56 |
- <li v-for="(order, idx) of orders" :key="idx"> |
|
57 |
- <input type="radio" :id="order.key" name="orders" :value="order.key" |
|
58 |
- v-model="searchReqDTO.order" /> |
|
59 |
- <label :for="order.key">{{ order.value }}</label> |
|
60 |
- </li> |
|
61 |
- </ul> |
|
62 |
- </dd> |
|
63 |
- <div class="btn-group"> |
|
64 |
- <button class="reset"><img :src="reseticon" alt=""> |
|
65 |
- <p>초기화</p> |
|
66 |
- </button> |
|
67 |
- <button class="search"><img :src="searchicon" alt=""> |
|
68 |
- <p>검색</p> |
|
69 |
- </button> |
|
70 |
- </div> |
|
71 |
- |
|
72 |
- </dl> |
|
73 |
- |
|
74 |
- </div> |
|
75 |
- <div class="search-result"> |
|
76 |
- <div class="tabs"> |
|
77 |
- <div class="flex-sp-bw mb-20 align-center"> |
|
78 |
- <div class="resultext "> |
|
79 |
- <img :src="resulticon" alt=""> |
|
80 |
- <p>총 <b>{{ count }}개</b>의 사진 기록물이 검색되었습니다. </p> |
|
81 |
- </div> |
|
82 |
- <div class="flex "> |
|
83 |
- <ul class="tab-box mb-20"> |
|
84 |
- <li v-for="(tab, index) in tabs" :key="index" class="tab-title" |
|
85 |
- :class="{ active: selectedTab === tab.id }" @click="selectTab(tab.id)"> |
|
86 |
- <img :src="selectedTab === tab.id ? tab.activeImage : tab.inactiveImage" |
|
87 |
- :alt="tab.title" class="tab-icon" /> |
|
88 |
- <p><b>{{ tab.title }}</b></p> |
|
89 |
- </li> |
|
90 |
- </ul> |
|
91 |
- <div class="select-box"> |
|
92 |
- <select v-model="itemsPerPage" @change="changeItemsPerPage"> |
|
93 |
- <option :value="5" selected>5개</option> |
|
94 |
- <option :value="10">10개</option> |
|
95 |
- <option :value="15">15개</option> |
|
96 |
- </select> |
|
97 |
- </div> |
|
98 |
- </div> |
|
99 |
- |
|
100 |
- </div> |
|
101 |
- |
|
102 |
- <div class="tab-content"> |
|
103 |
- <!-- Loop through tabContents, and only display content that matches selectedTab --> |
|
104 |
- <div v-for="(tabContent, idx) in tabContents" :key="idx"> |
|
105 |
- <!-- Display content only if the tab's ID matches the selectedTab --> |
|
106 |
- <div v-show="tabContent.id === selectedTab"> |
|
107 |
- <!-- 카드형 Section (Card Layout) --> |
|
108 |
- <div v-if="tabContent.viewType === 'card'"> |
|
109 |
- <ul class="card-wrap"> |
|
110 |
- <li v-for="(resultitem, index) in paginatedItems" :key="index" class="mb-30"> |
|
111 |
- <div class="result-box"> |
|
112 |
- <!-- Main Image Section --> |
|
113 |
- <div class="main-img"> |
|
114 |
- <img :src="resultitem.img" alt="" class="tab-image" /> |
|
115 |
- </div> |
|
116 |
- <!-- Text Section --> |
|
117 |
- <div class="text-box"> |
|
118 |
- <router-link :to="{ path: '/PicHistoryDetail.page' }"> |
|
119 |
- <h5>{{ resultitem.title }}</h5> |
|
120 |
- </router-link> |
|
121 |
- |
|
122 |
- <p class="address">{{ resultitem.address }}</p> |
|
123 |
- <p class="text">{{ resultitem.content }}</p> |
|
124 |
- |
|
125 |
- <div class="mb-20"> |
|
126 |
- <ul class="category"> |
|
127 |
- <li v-if="resultitem.category1" class="category1">카테고리1</li> |
|
128 |
- <li v-if="resultitem.category2" class="category2">카테고리2</li> |
|
129 |
- </ul> |
|
130 |
- </div> |
|
131 |
- |
|
132 |
- <div class="date"> |
|
133 |
- <ul> |
|
134 |
- <li>생산연도 <b>{{ resultitem.year }}</b></li> |
|
135 |
- <li>|</li> |
|
136 |
- <li>등록 <b>{{ resultitem.date }}</b></li> |
|
137 |
- </ul> |
|
138 |
- </div> |
|
139 |
- </div> |
|
140 |
- </div> |
|
141 |
- </li> |
|
142 |
- </ul> |
|
143 |
- |
|
144 |
- <!-- Empty State if no results in paginatedItems --> |
|
145 |
- <div v-if="paginatedItems.length === 0" class="no-results"> |
|
146 |
- <p>등록된 게시물이 없습니다.</p> |
|
147 |
- </div> |
|
148 |
- </div> |
|
149 |
- |
|
150 |
- <!-- 리스트형 Section (List Layout) --> |
|
151 |
- <div v-if="tabContent.viewType === 'list'"> |
|
152 |
- <ul class="list-wrap"> |
|
153 |
- <li v-for="(resultitem, index) in paginatedItems" :key="index" class="mb-30"> |
|
154 |
- <div class="text-box"> |
|
155 |
- <h5>{{ resultitem.title }}</h5> |
|
156 |
- <p class="address">{{ resultitem.address }}</p> |
|
157 |
- |
|
158 |
- <div class="flex-sp-bw"> |
|
159 |
- <div class="mb-20"> |
|
160 |
- <ul class="category"> |
|
161 |
- <li v-if="resultitem.category1" class="category1">카테고리1</li> |
|
162 |
- <li v-if="resultitem.category2" class="category2">카테고리2</li> |
|
163 |
- </ul> |
|
164 |
- </div> |
|
165 |
- |
|
166 |
- <div class="date "> |
|
167 |
- <ul> |
|
168 |
- <li>생산연도 <b>{{ resultitem.year }}</b></li> |
|
169 |
- <li>|</li> |
|
170 |
- <li>등록 <b>{{ resultitem.date }}</b></li> |
|
171 |
- </ul> |
|
172 |
- </div> |
|
173 |
- </div> |
|
174 |
- </div> |
|
175 |
- </li> |
|
176 |
- </ul> |
|
177 |
- |
|
178 |
- <!-- Empty State if no results in paginatedItems --> |
|
179 |
- <div v-if="paginatedItems.length === 0" class="no-results"> |
|
180 |
- <p>등록된 게시물이 없습니다.</p> |
|
181 |
- </div> |
|
182 |
- </div> |
|
183 |
- </div> |
|
184 |
- </div> |
|
185 |
- </div> |
|
186 |
- </div> |
|
187 |
- |
|
188 |
- <div class="btn-group flex-end mt-40"><button class="register"> <router-link |
|
189 |
- :to="{ path: '/PicHistoryInsert.page' }">등록</router-link></button></div> |
|
190 |
- <div class="pagination flex-center mt-40"> |
|
191 |
- |
|
192 |
- <!-- Previous and Next Page Buttons --> |
|
193 |
- <button> |
|
194 |
- <DoubleLeftOutlined /> |
|
195 |
- </button> |
|
196 |
- <button @click="previousPage" :disabled="currentPage === 1"> |
|
197 |
- <LeftOutlined /> |
|
198 |
- </button> |
|
199 |
- <button class="page-number clicked">1</button> |
|
200 |
- <button @click="nextPage" :disabled="currentPage === totalPages"> |
|
201 |
- <RightOutlined /> |
|
202 |
- </button> |
|
203 |
- <button> |
|
204 |
- <DoubleRightOutlined /> |
|
205 |
- </button> |
|
206 |
- </div> |
|
207 |
- </div> |
|
2 |
+ <div class="content"> |
|
3 |
+ <div class="sub-title-area mb-30"> |
|
4 |
+ <h2>사진 기록물</h2> |
|
5 |
+ <div class="breadcrumb-list"> |
|
6 |
+ <ul> |
|
7 |
+ <li> |
|
8 |
+ <img :src="homeicon" alt="Home Icon"> |
|
9 |
+ <p>기록물</p> |
|
10 |
+ </li> |
|
11 |
+ <li><img :src="righticon" alt=""></li> |
|
12 |
+ <li>사진 기록물</li> |
|
13 |
+ </ul> |
|
14 |
+ </div> |
|
208 | 15 |
</div> |
209 |
- |
|
16 |
+ <div class="search-form form"> |
|
17 |
+ <dl> |
|
18 |
+ <dd class="mb-15"> |
|
19 |
+ <p>검색범위</p> |
|
20 |
+ <ul> |
|
21 |
+ <li> |
|
22 |
+ <input type="checkbox" id="allScope" v-model="isChkAllScope" @change="fnChkAllOptions" /> |
|
23 |
+ <label for="allScope">전체</label> |
|
24 |
+ </li> |
|
25 |
+ <li> |
|
26 |
+ <input type="checkbox" id="searchSj" v-model="searchReqDTO.useSj" @change="fnChkOption" /> |
|
27 |
+ <label for="searchSj">제목</label> |
|
28 |
+ </li> |
|
29 |
+ <li> |
|
30 |
+ <input type="checkbox" id="searchCn" v-model="searchReqDTO.useCn" @change="fnChkOption" /> |
|
31 |
+ <label for="searchCn">내용</label> |
|
32 |
+ </li> |
|
33 |
+ <li> |
|
34 |
+ <input type="checkbox" id="searchAdres" v-model="searchReqDTO.useAdres" @change="fnChkOption" /> |
|
35 |
+ <label for="searchAdres">주소</label> |
|
36 |
+ </li> |
|
37 |
+ </ul> |
|
38 |
+ </dd> |
|
39 |
+ <dd class="mb-15"> |
|
40 |
+ <p>검색어</p> |
|
41 |
+ <div class="wfull"><input type="text" v-model="searchReqDTO.searchText" v-on:keyup.enter="fnSearch()"></div> |
|
42 |
+ </dd> |
|
43 |
+ <dd class="mb-15"> |
|
44 |
+ <p>생산연도</p> |
|
45 |
+ <input type="date" v-model="searchReqDTO.startYear"> |
|
46 |
+ <p class="mark">~</p> |
|
47 |
+ <input type="date" v-model="searchReqDTO.endYear"> |
|
48 |
+ </dd> |
|
49 |
+ <dd class="mb-20"> |
|
50 |
+ <p>카테고리</p> |
|
51 |
+ <ul> |
|
52 |
+ <li v-for="(category, idx) of categorys" :key="idx"> |
|
53 |
+ <input type="checkbox" :id="category.ctgryId" name="categorys" :value="category.ctgryId" v-model="searchReqDTO.searchCtgries" /> |
|
54 |
+ <label :for="category.ctgryId">{{ category.ctgryNm }}</label> |
|
55 |
+ </li> |
|
56 |
+ </ul> |
|
57 |
+ </dd> |
|
58 |
+ <dd class="mb-15"> |
|
59 |
+ <p>정렬</p> |
|
60 |
+ <ul> |
|
61 |
+ <li v-for="(order, idx) of orders" :key="idx"> |
|
62 |
+ <input type="radio" :id="order.key" name="orders" :value="order.key" v-model="searchReqDTO.order" /> |
|
63 |
+ <label :for="order.key">{{ order.value }}</label> |
|
64 |
+ </li> |
|
65 |
+ </ul> |
|
66 |
+ </dd> |
|
67 |
+ <div class="btn-group"> |
|
68 |
+ <button type="button" class="reset" @click="init"> |
|
69 |
+ <img :src="reseticon" alt=""> |
|
70 |
+ <p>초기화</p> |
|
71 |
+ </button> |
|
72 |
+ <button type="button" class="search" @click="fnSearch"> |
|
73 |
+ <img :src="searchicon" alt=""> |
|
74 |
+ <p>검색</p> |
|
75 |
+ </button> |
|
76 |
+ </div> |
|
77 |
+ </dl> |
|
78 |
+ </div> |
|
79 |
+ <div class="search-result"> |
|
80 |
+ <div class="tabs"> |
|
81 |
+ <div class="flex-sp-bw mb-20 align-center"> |
|
82 |
+ <div class="resultext "> |
|
83 |
+ <img :src="resulticon" alt=""> |
|
84 |
+ <p>총 <b>{{ searchReqDTO.totalRecordCount }}개</b>의 사진 기록물이 검색되었습니다. </p> |
|
85 |
+ </div> |
|
86 |
+ <div class="flex"> |
|
87 |
+ <ul class="tab-box mb-20"> |
|
88 |
+ <li v-for="(tab, idx) in tabs" :key="idx" class="tab-title" :class="{ active: selectedTabId === tab.id }" @click="selectTab(tab.id)"> |
|
89 |
+ <img :src="selectedTabId === tab.id ? tab.activeImage : tab.inactiveImage" :alt="tab.title" class="tab-icon" /> |
|
90 |
+ <p><b>{{ tab.title }}</b></p> |
|
91 |
+ </li> |
|
92 |
+ </ul> |
|
93 |
+ <div class="select-box"> |
|
94 |
+ <select v-model="searchReqDTO.recordSize" @change="fnSearch"> |
|
95 |
+ <option :value="24">24개</option> |
|
96 |
+ <option :value="36">36개</option> |
|
97 |
+ <option :value="100">100개</option> |
|
98 |
+ </select> |
|
99 |
+ </div> |
|
100 |
+ </div> |
|
101 |
+ </div> |
|
102 |
+ <div class="tab-content"> |
|
103 |
+ <div v-if="searchResult.length > 0"> |
|
104 |
+ <CardStyleComponent v-if="selectedTabId === 'CARD'" :name="'P'" :list="searchResult" /> |
|
105 |
+ <ListStyleComponent v-if="selectedTabId === 'LIST'" :name="'P'" :list="searchResult" /> |
|
106 |
+ </div> |
|
107 |
+ <div v-else class="no-results"> |
|
108 |
+ <p>등록된 게시물이 없습니다.</p> |
|
109 |
+ </div> |
|
110 |
+ </div> |
|
111 |
+ </div> |
|
112 |
+ <div class="btn-group flex-end mt-40"><button class="register"> <router-link :to="{ path: '/PicHistoryInsert.page' }">등록</router-link></button></div> |
|
113 |
+ <DefaultPagination class="mt-40" :search="searchReqDTO" @onChange="fnChangeCurrentPage" /> |
|
114 |
+ </div> |
|
115 |
+ </div> |
|
210 | 116 |
</template> |
211 | 117 |
<script> |
212 |
-import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
|
213 |
-import { findAllCategoryProc } from "../../../resources/api/category"; // 카테고리 목록 검색 |
|
118 |
+// COMPONENT |
|
119 |
+import CardStyleComponent from '@/views/component/listLayout/CardStyleComponent.vue'; |
|
120 |
+import ListStyleComponent from '@/views/component/listLayout/ListStyleComponent.vue'; |
|
121 |
+import DefaultPagination from '@/views/component/DefaultPagination.vue'; |
|
122 |
+// API |
|
123 |
+import { findAllByNullProc } from "@/resources/api/category"; |
|
124 |
+import { findDcrysProc } from "@/resources/api/dcry"; |
|
214 | 125 |
|
215 | 126 |
export default { |
216 |
- components: { |
|
217 |
- DoubleLeftOutlined, |
|
218 |
- LeftOutlined, |
|
219 |
- RightOutlined, |
|
220 |
- DoubleRightOutlined, |
|
221 |
- }, |
|
222 |
- data() { |
|
223 |
- return { |
|
224 |
- selectedTab: 1, |
|
225 |
- // 검색용 객체 |
|
226 |
- searchReqDTO: { |
|
227 |
- searchType: [], |
|
228 |
- searchText: null, |
|
229 |
- startYear: null, |
|
230 |
- endYear: null, |
|
231 |
- searchTy: null, |
|
232 |
- searchCtgry: [], |
|
233 |
- order: "rgsde", |
|
234 |
- }, |
|
235 |
- tabs: [ |
|
127 |
+ components: { |
|
128 |
+ DefaultPagination, |
|
129 |
+ CardStyleComponent, |
|
130 |
+ ListStyleComponent, |
|
131 |
+ }, |
|
236 | 132 |
|
237 |
- { |
|
238 |
- id: 1, |
|
239 |
- title: "카드형", |
|
240 |
- activeImage: "client/resources/images/list_icon01_on.png", // Active tab image |
|
241 |
- inactiveImage: "client/resources/images/list_icon01_off.png", |
|
242 |
- }, |
|
243 |
- { |
|
244 |
- id: 2, |
|
245 |
- title: "리스트형", |
|
246 |
- activeImage: "client/resources/images/list_icon02_on.png", // Active tab image |
|
247 |
- inactiveImage: "client/resources/images/list_icon02_off.png", |
|
248 |
- }, |
|
249 |
- ], |
|
250 |
- tabContents: [ |
|
251 |
- { id: 1, viewType: 'card', list: [{ sj: 'Item 1', rgsde: '2025-03-01', files: [{ filePath: 'image1.png' }] }] }, |
|
252 |
- { id: 2, viewType: 'list', list: [{ sj: 'Item 2', rgsde: '2025-03-02', files: [{ filePath: 'image2.png' }] }] }, |
|
253 |
- ], |
|
254 |
- paginatedItems: [], |
|
255 |
- resultitems: [ |
|
256 |
- { |
|
257 |
- img: 'client/resources/images/img6.png', |
|
258 |
- title: '사진 기록물 제목', |
|
259 |
- address: '경상북도 구미시 송정대로 55', |
|
260 |
- content: '대한민국 최대의 내륙 산업단지를 보유하고, 서울로부터 277km, 부산으로부터 167km 거리에 있으며, 면적은 615㎢로 경상북도 전체 면적의 3.2%에 달합니다. 인구는 41만 명이고, 선산읍, 고아읍, 산동읍을 비롯한 3읍, 5면, 17개 동으로 구성되어…', |
|
261 |
- category1: true, |
|
262 |
- category2: true, |
|
263 |
- year: 2020, |
|
264 |
- date: '2021-01-01' |
|
265 |
- }, |
|
133 |
+ data() { |
|
134 |
+ return { |
|
135 |
+ // ICON |
|
136 |
+ resulticon: "client/resources/images/icon/r-check.png", |
|
137 |
+ homeicon: 'client/resources/images/icon/home.png', |
|
138 |
+ searchicon: 'client/resources/images/icon/search.png', |
|
139 |
+ reseticon: 'client/resources/images/icon/reset.png', |
|
140 |
+ righticon: 'client/resources/images/icon/right.png', |
|
266 | 141 |
|
267 |
- ], |
|
268 |
- currentPage: 1, // Current page number |
|
269 |
- itemsPerPage: 5, |
|
270 |
- resulticon: "client/resources/images/icon/r-check.png", |
|
271 |
- homeicon: 'client/resources/images/icon/home.png', |
|
272 |
- searchicon: 'client/resources/images/icon/search.png', |
|
273 |
- reseticon: 'client/resources/images/icon/reset.png', |
|
274 |
- righticon: 'client/resources/images/icon/right.png', |
|
275 |
- count: 23, |
|
276 |
- checkOptions: [ |
|
277 |
- '전체', |
|
278 |
- '사진', |
|
279 |
- '영상', |
|
280 |
- '미디어 영상', |
|
281 |
- '보도자료', |
|
282 |
- ], |
|
283 |
- checkOptions2: [ |
|
284 |
- '전체', |
|
285 |
- '제목', |
|
286 |
- '내용', |
|
287 |
- '주소', |
|
288 |
- ], |
|
289 |
- checkOptions3: [ |
|
290 |
- '카테고리1', |
|
291 |
- '카테고리2', |
|
292 |
- '카테고리3', |
|
293 |
- '카테고리4', |
|
294 |
- '카테고리5', |
|
295 |
- ], |
|
296 |
- checkOptions4: [ |
|
297 |
- '최신', |
|
298 |
- '인기', |
|
299 |
- ], |
|
300 |
- isChkAllScope: false, // 검색범위 전체 체크 여부 |
|
301 |
- searchType: [ |
|
302 |
- { key: "sj", value: "제목" }, |
|
303 |
- { key: "cn", value: "내용" }, |
|
304 |
- { key: "adres", value: "주소" }, |
|
305 |
- ], // 검색범위 목록 |
|
306 |
- categorys: [], // 카테고리 목록 |
|
307 |
- orders: [ |
|
308 |
- { key: "rgsde", value: "최신" }, |
|
309 |
- { key: "rdcnt", value: "인기" }, |
|
310 |
- ], // 정렬 목록 |
|
311 |
- }; |
|
312 |
- }, |
|
313 |
- computed: { |
|
314 |
- // Total number of pages |
|
315 |
- totalPages() { |
|
316 |
- return Math.ceil(this.resultitems.length / this.itemsPerPage); |
|
317 |
- }, |
|
142 |
+ // 검색용 객체 |
|
143 |
+ isChkAllScope: true, // 검색범위 전체 체크 여부 |
|
144 |
+ searchType: [ |
|
145 |
+ { key: "sj", value: "제목" }, |
|
146 |
+ { key: "cn", value: "내용" }, |
|
147 |
+ { key: "adres", value: "주소" }, |
|
148 |
+ ], // 검색범위 목록 |
|
149 |
+ categorys: [], // 카테고리 목록 |
|
150 |
+ orders: [ |
|
151 |
+ { key: "rgsde", value: "최신" }, |
|
152 |
+ { key: "rdcnt", value: "인기" }, |
|
153 |
+ ], // 정렬 목록 |
|
318 | 154 |
|
319 |
- // Paginated items based on current page and items per page |
|
320 |
- paginatedItems() { |
|
321 |
- const start = (this.currentPage - 1) * this.itemsPerPage; |
|
322 |
- const end = start + this.itemsPerPage; |
|
323 |
- return this.resultitems.slice(start, end); |
|
324 |
- }, |
|
325 |
- }, |
|
326 |
- created() { |
|
327 |
- // 초기 데이터 세팅 |
|
328 |
- this.isChkAllScope = true; |
|
329 |
- this.searchReqDTO.searchType = this.searchType.map(item => item.key); |
|
330 |
- this.searchReqDTO.order = this.orders[0].key |
|
155 |
+ // 검색용 객체 초기값 |
|
156 |
+ searchDefault: { |
|
157 |
+ useSj: true, |
|
158 |
+ useCn: true, |
|
159 |
+ useAdres: true, |
|
160 |
+ searchText: null, |
|
161 |
+ startYear: null, |
|
162 |
+ endYear: null, |
|
163 |
+ searchTy: "P", |
|
164 |
+ searchCtgries: [], |
|
165 |
+ order: "rgsde", |
|
166 |
+ // 페이지네이션 |
|
167 |
+ currentPage: 1, // 현재 페이지 |
|
168 |
+ recordSize: 24, // 한 페이지에 표시할 데이터 개수 |
|
169 |
+ }, |
|
170 |
+ searchReqDTO: {}, // 실제 검색에 사용되는 객체 |
|
331 | 171 |
|
332 |
- this.fnFindCategorys(); // 카테고리 목록 조회 (검색조건 없음) |
|
333 |
- }, |
|
334 |
- methods: { |
|
335 |
- selectTab(tabId) { |
|
336 |
- this.selectedTab = tabId; // Update the selected tab index |
|
337 |
- }, |
|
338 |
- // Change the number of items displayed per page |
|
339 |
- changeItemsPerPage() { |
|
340 |
- this.currentPage = 1; // Reset to first page when changing items per page |
|
341 |
- }, |
|
342 |
- previousPage() { |
|
343 |
- if (this.currentPage > 1) { |
|
344 |
- this.currentPage--; |
|
345 |
- } |
|
346 |
- }, |
|
172 |
+ searchResult: [], // 검색결과 |
|
347 | 173 |
|
348 |
- // Go to the next page |
|
349 |
- nextPage() { |
|
350 |
- if (this.currentPage < this.totalPages) { |
|
351 |
- this.currentPage++; |
|
352 |
- } |
|
174 |
+ // 목록 레이아웃 |
|
175 |
+ selectedTabId: null, |
|
176 |
+ tabs: [ |
|
177 |
+ { |
|
178 |
+ id: "CARD", |
|
179 |
+ title: "카드형", |
|
180 |
+ activeImage: "client/resources/images/list_icon01_on.png", // Active tab image |
|
181 |
+ inactiveImage: "client/resources/images/list_icon01_off.png", |
|
353 | 182 |
}, |
354 |
- isChkAllScope: false, // 검색범위 전체 체크 여부 |
|
355 |
- searchType: [ |
|
356 |
- { key: "sj", value: "제목" }, |
|
357 |
- { key: "cn", value: "내용" }, |
|
358 |
- { key: "adres", value: "주소" }, |
|
359 |
- ], // 검색범위 목록 |
|
360 |
- categorys: [], // 카테고리 목록 |
|
361 |
- orders: [ |
|
362 |
- { key: "rgsde", value: "최신" }, |
|
363 |
- { key: "rdcnt", value: "인기" }, |
|
364 |
- ], // 정렬 목록 |
|
365 |
- |
|
366 |
- async fnFindCategorys() { |
|
367 |
- try { |
|
368 |
- const response = await findAllCategoryProc(); |
|
369 |
- this.categorys = response.data.data.ctgry; |
|
370 |
- } catch (error) { |
|
371 |
- if (error.response) { |
|
372 |
- console.log("에러 응답:", error.response.data); |
|
373 |
- } |
|
374 |
- console.error("Error:", error); |
|
375 |
- } |
|
183 |
+ { |
|
184 |
+ id: "LIST", |
|
185 |
+ title: "리스트형", |
|
186 |
+ activeImage: "client/resources/images/list_icon02_on.png", // Active tab image |
|
187 |
+ inactiveImage: "client/resources/images/list_icon02_off.png", |
|
376 | 188 |
}, |
189 |
+ ], |
|
377 | 190 |
|
378 |
- // 통합검색 |
|
379 |
- async fnFindAllDatas() { |
|
380 |
- try { |
|
381 |
- let params = {}; |
|
382 |
- if (this.searchReqDTO.searchRecord.length > 0) { |
|
383 |
- params.searchRecords = this.searchReqDTO.searchRecord.join(','); |
|
384 |
- } |
|
385 |
- if (this.searchReqDTO.searchType.length > 0) { |
|
386 |
- params.searchTypes = this.searchReqDTO.searchType.join(','); |
|
387 |
- } |
|
388 |
- if (this.searchReqDTO.searchCtgry.length > 0) { |
|
389 |
- params.searchCtgries = this.searchReqDTO.searchCtgry.join(','); |
|
390 |
- } |
|
391 |
- params.searchText = this.searchReqDTO.searchText; |
|
392 |
- params.startYear = this.searchReqDTO.startYear; |
|
393 |
- params.endYear = this.searchReqDTO.endYear; |
|
394 |
- params.order = this.searchReqDTO.order; |
|
191 |
+ isInitialLoad: true // 초기 로드 여부 |
|
192 |
+ }; |
|
193 |
+ }, |
|
395 | 194 |
|
396 |
- // API 호출 |
|
397 |
- const response = await findAllDatas(params); |
|
398 |
- this.searchResult = response.data.data.searchResult; |
|
399 |
- } catch (error) { |
|
400 |
- if (error.response) { |
|
401 |
- console.log("에러 응답:", error.response.data); |
|
402 |
- } |
|
403 |
- console.error("Error:", error); |
|
404 |
- } |
|
405 |
- }, |
|
195 |
+ created() { |
|
196 |
+ this.init(); // 초기화 |
|
197 |
+ this.fnFindCategorys(); // 카테고리 목록 조회 (검색조건 없음) |
|
198 |
+ }, |
|
199 |
+ |
|
200 |
+ mounted() { |
|
201 |
+ let searchText = this.$route.query.searchText; |
|
202 |
+ if (searchText !== null) { |
|
203 |
+ this.searchReqDTO.searchText = searchText; |
|
204 |
+ } |
|
205 |
+ |
|
206 |
+ this.fnSearch(); // 통합검색 |
|
207 |
+ }, |
|
208 |
+ |
|
209 |
+ methods: { |
|
210 |
+ // 초기화 |
|
211 |
+ init() { |
|
212 |
+ if (this.isInitialLoad) { |
|
213 |
+ this.isInitialLoad = false; |
|
214 |
+ } else { |
|
215 |
+ if (!confirm('검색 조건을 초기화하시겠습니까?')) { |
|
216 |
+ return; |
|
217 |
+ } |
|
218 |
+ } |
|
219 |
+ |
|
220 |
+ this.searchReqDTO = JSON.parse(JSON.stringify(this.searchDefault)); |
|
221 |
+ this.searchResult = []; // 검색결과 초기화 |
|
222 |
+ |
|
223 |
+ this.selectedTabId = this.tabs[0].id; |
|
406 | 224 |
}, |
407 | 225 |
|
226 |
+ // 카테고리 목록 조회 |
|
227 |
+ async fnFindCategorys() { |
|
228 |
+ try { |
|
229 |
+ const response = await findAllByNullProc(); |
|
230 |
+ this.categorys = response.data.data.ctgry; |
|
231 |
+ } catch (error) { |
|
232 |
+ this.categorys = []; // 카테고리 목록 초기화 |
|
408 | 233 |
|
234 |
+ if (error.response) { |
|
235 |
+ alert(error.response.data.message); |
|
236 |
+ } |
|
237 |
+ console.error(error.message); |
|
238 |
+ } |
|
239 |
+ }, |
|
409 | 240 |
|
241 |
+ // 페이지 이동 |
|
242 |
+ fnChangeCurrentPage(currentPage) { |
|
243 |
+ this.searchReqDTO.currentPage = Number(currentPage); |
|
244 |
+ this.$nextTick(() => { |
|
245 |
+ this.fnFindCategorys(); |
|
246 |
+ }); |
|
247 |
+ }, |
|
248 |
+ |
|
249 |
+ // 통합검색 |
|
250 |
+ async fnSearch() { |
|
251 |
+ try { |
|
252 |
+ // 깊은 복사로 파라미터 생성 |
|
253 |
+ const params = JSON.parse(JSON.stringify(this.searchReqDTO)); |
|
254 |
+ |
|
255 |
+ // 디버깅용 로그 - 실제 전송되는 값 확인 |
|
256 |
+ console.log("검색 파라미터:", params); |
|
257 |
+ |
|
258 |
+ // 카테고리 목록 처리 |
|
259 |
+ if (this.searchReqDTO.searchCtgries && this.searchReqDTO.searchCtgries.length > 0) { |
|
260 |
+ params.searchCtgries = this.searchReqDTO.searchCtgries.join(','); |
|
261 |
+ } else { |
|
262 |
+ delete params.searchCtgries; |
|
263 |
+ } |
|
264 |
+ |
|
265 |
+ // API 호출 |
|
266 |
+ const response = await findDcrysProc(params); |
|
267 |
+ this.searchResult = response.data.data.dcrys; |
|
268 |
+ this.searchReqDTO = response.data.data.search; |
|
269 |
+ } catch (error) { |
|
270 |
+ this.searchResult = []; // 검색결과 초기화 |
|
271 |
+ |
|
272 |
+ if (error.response) { |
|
273 |
+ alert(error.response.data.message); |
|
274 |
+ } |
|
275 |
+ console.error(error.message); |
|
276 |
+ } |
|
277 |
+ }, |
|
278 |
+ |
|
279 |
+ // 기록유형 전체 선택 여부 변경 |
|
280 |
+ fnChkAllOptions() { |
|
281 |
+ this.searchReqDTO.useSj = this.isChkAllScope; |
|
282 |
+ this.searchReqDTO.useCn = this.isChkAllScope; |
|
283 |
+ this.searchReqDTO.useAdres = this.isChkAllScope; |
|
284 |
+ }, |
|
285 |
+ |
|
286 |
+ // 기록유형 선택 여부 변경 |
|
287 |
+ fnChkOption() { |
|
288 |
+ this.isChkAllScope = this.searchReqDTO.useSj && this.searchReqDTO.useCn && this.searchReqDTO.useAdres; |
|
289 |
+ }, |
|
290 |
+ |
|
291 |
+ selectTab(tabId) { |
|
292 |
+ this.selectedTabId = tabId; |
|
293 |
+ }, |
|
294 |
+ }, |
|
410 | 295 |
}; |
411 |
-</script> |
|
412 |
-<style scoped></style>(파일 끝에 줄바꿈 문자 없음) |
|
296 |
+</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/user/TotalSearch.vue
+++ client/views/pages/user/TotalSearch.vue
... | ... | @@ -107,10 +107,11 @@ |
107 | 107 |
</div> |
108 | 108 |
</template> |
109 | 109 |
<script> |
110 |
-// 통합 검색 |
|
111 |
-import { findAllDatas } from "../../../resources/api/main"; |
|
110 |
+// COMPONENT |
|
111 |
+import CardViewList from "../../component/CardViewList.vue"; |
|
112 |
+// API |
|
113 |
+import { findAllDatas } from "../../../resources/api/main"; // 통합 검색 |
|
112 | 114 |
import { findAllByNullProc } from "../../../resources/api/category"; // 카테고리 목록 검색 |
113 |
-import CardViewList from "../../component/List/CardViewList.vue"; |
|
114 | 115 |
|
115 | 116 |
export default { |
116 | 117 |
components: { |
... | ... | @@ -140,7 +141,6 @@ |
140 | 141 |
searchCtgries: [], |
141 | 142 |
order: "rgsde", |
142 | 143 |
}, |
143 |
- |
|
144 | 144 |
searchReqDTO: {}, |
145 | 145 |
|
146 | 146 |
isChkAllRecord: true, // 기록유형 전체 체크 여부 |
--- client/views/pages/user/VideoHistoryInsert.vue
+++ client/views/pages/user/VideoHistoryInsert.vue
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 |
<script> |
89 | 89 |
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
90 | 90 |
// COMPONENT |
91 |
-import EditorComponent from '../../component/EditorComponent.vue'; |
|
91 |
+import EditorComponent from '../../component/editor/EditorComponent.vue'; |
|
92 | 92 |
import CategorySelectModal from '../../component/modal/CategorySelectModal.vue'; |
93 | 93 |
|
94 | 94 |
export default { |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?