
--- client/resources/api/sanctns.js
+++ client/resources/api/sanctns.js
... | ... | @@ -2,5 +2,5 @@ |
2 | 2 |
|
3 | 3 |
// 조회 - 목록 |
4 | 4 |
export const findSanctnsProc = data => { |
5 |
- return apiClient.get('/sanctn/findSanctns.json', data); |
|
5 |
+ return apiClient.get('/sanctn/findSanctns.json', { params: data }); |
|
6 | 6 |
}(파일 끝에 줄바꿈 문자 없음) |
--- client/resources/api/vcatn.js
+++ client/resources/api/vcatn.js
... | ... | @@ -11,8 +11,8 @@ |
11 | 11 |
} |
12 | 12 |
|
13 | 13 |
// 조회 - 목록 |
14 |
-export const findMyVcatnsProc = data => { |
|
15 |
- return apiClient.get('/vcatn/findMyVcatns.json', { params: data }); |
|
14 |
+export const findVcatnsProc = data => { |
|
15 |
+ return apiClient.get('/vcatn/findVcatns.json', { params: data }); |
|
16 | 16 |
} |
17 | 17 |
|
18 | 18 |
// 조회 - 상세 |
--- client/resources/js/cmmnPlugin.js
+++ client/resources/js/cmmnPlugin.js
... | ... | @@ -55,11 +55,23 @@ |
55 | 55 |
} |
56 | 56 |
|
57 | 57 |
// 날짜 형식 변경 |
58 |
- Vue.config.globalProperties.$formattedDate = (day, hour, min) => { |
|
59 |
- let beginHour = hour ? hour.toString().padStart(2, '0') : '00'; |
|
60 |
- let beginMnt = min ? min.toString().padStart(2, '0') : '00'; |
|
58 |
+ Vue.config.globalProperties.$formattedDate = (d, h, m) => { |
|
59 |
+ if (Vue.config.globalProperties.$isEmpty(d) || Vue.config.globalProperties.$isEmpty(h) || Vue.config.globalProperties.$isEmpty(m)) { |
|
60 |
+ return; |
|
61 |
+ } |
|
62 |
+ let day = d.split(' ')[0]; |
|
63 |
+ let hour = h.toString().padStart(2, '0'); |
|
64 |
+ let minute = m.toString().padStart(2, '0'); |
|
61 | 65 |
|
62 |
- return day.split(' ')[0] + " " + beginHour + ":" + beginMnt |
|
66 |
+ return day + " " + hour + ":" + minute |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ // 기간 형식 변경 |
|
70 |
+ Vue.config.globalProperties.$formattedDates = (item) => { |
|
71 |
+ const startDate = Vue.config.globalProperties.$formattedDate(item.bgnde, item.beginHour, item.beginMnt); |
|
72 |
+ const endDate = Vue.config.globalProperties.$formattedDate(item.endde, item.endHour, item.endMnt); |
|
73 |
+ |
|
74 |
+ return startDate + " ~ " + endDate; |
|
63 | 75 |
} |
64 | 76 |
|
65 | 77 |
// 공통코드 조회 (부모 코드로 자식 코드 조회) |
--- client/views/pages/Employee/ChuljangList.vue
+++ client/views/pages/Employee/ChuljangList.vue
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 |
<td>{{ item.where }}</td> |
71 | 71 |
<td>{{ item.purpose }}</td> |
72 | 72 |
<td >{{ item.selectedMember }} |
73 |
- |
|
73 |
+ |
|
74 | 74 |
</td> |
75 | 75 |
</tr> |
76 | 76 |
</tbody> |
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 |
|
102 | 102 |
}, |
103 | 103 |
methods: { |
104 |
- |
|
104 |
+ |
|
105 | 105 |
registerLeave() { |
106 | 106 |
console.log("등록 버튼 클릭됨"); |
107 | 107 |
|
... | ... | @@ -150,7 +150,6 @@ |
150 | 150 |
created() { |
151 | 151 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
152 | 152 |
const storedData = localStorage.getItem('ChuljangFormData'); |
153 |
- console.log(storedData); |
|
154 | 153 |
if (storedData) { |
155 | 154 |
// Parse the data and wrap it in an array |
156 | 155 |
const parsedData = JSON.parse(storedData); |
... | ... | @@ -159,10 +158,10 @@ |
159 | 158 |
} |
160 | 159 |
}, |
161 | 160 |
mounted() { |
162 |
- |
|
161 |
+ |
|
163 | 162 |
// 처음에는 모든 데이터를 표시 |
164 | 163 |
this.filteredData = this.ChuljangData; |
165 |
- |
|
164 |
+ |
|
166 | 165 |
}, |
167 | 166 |
}; |
168 | 167 |
</script> |
--- client/views/pages/Employee/HyugaList.vue
+++ client/views/pages/Employee/HyugaList.vue
... | ... | @@ -145,13 +145,12 @@ |
145 | 145 |
}); |
146 | 146 |
} |
147 | 147 |
}, |
148 |
- |
|
148 |
+ |
|
149 | 149 |
|
150 | 150 |
}, |
151 | 151 |
created() { |
152 | 152 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
153 | 153 |
const storedData = localStorage.getItem('HyugaFormData'); |
154 |
- console.log(storedData); |
|
155 | 154 |
if (storedData) { |
156 | 155 |
// Parse the data and wrap it in an array |
157 | 156 |
const parsedData = JSON.parse(storedData); |
--- client/views/pages/Employee/HyugaOk.vue
+++ client/views/pages/Employee/HyugaOk.vue
... | ... | @@ -145,13 +145,12 @@ |
145 | 145 |
}); |
146 | 146 |
} |
147 | 147 |
}, |
148 |
- |
|
148 |
+ |
|
149 | 149 |
|
150 | 150 |
}, |
151 | 151 |
created() { |
152 | 152 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
153 | 153 |
const storedData = localStorage.getItem('HyugaFormData'); |
154 |
- console.log(storedData); |
|
155 | 154 |
if (storedData) { |
156 | 155 |
// Parse the data and wrap it in an array |
157 | 156 |
const parsedData = JSON.parse(storedData); |
--- client/views/pages/Manager/approval/approval.vue
+++ client/views/pages/Manager/approval/approval.vue
... | ... | @@ -127,7 +127,6 @@ |
127 | 127 |
created() { |
128 | 128 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
129 | 129 |
const storedData = localStorage.getItem('DeptData'); |
130 |
- console.log(storedData); |
|
131 | 130 |
if (storedData) { |
132 | 131 |
this.DeptData = JSON.parse(storedData); |
133 | 132 |
} |
--- client/views/pages/Manager/approval/approvalList.vue
+++ client/views/pages/Manager/approval/approvalList.vue
... | ... | @@ -6,19 +6,13 @@ |
6 | 6 |
<div class="sch-form-wrap title-wrap"> |
7 | 7 |
<h3><img :src="h3icon" alt="">승인 대기</h3> |
8 | 8 |
<div class="input-group"> |
9 |
- <select name="" id="" class="form-select"> |
|
10 |
- <option :value="currentYear">{{ currentYear }}년</option> |
|
11 |
- <option value="all">전체</option> |
|
12 |
- <template v-for="year in remainingYears" :key="year"> |
|
13 |
- <option :value="year" v-if="year !== currentYear"> {{ year }}년</option> |
|
14 |
- </template> |
|
9 |
+ <select class="form-select" v-model="waitRequest.year" @change="fnChangeCurrentPage(1, 'wait')"> |
|
10 |
+ <option value="">연도 전체</option> |
|
11 |
+ <option v-for="year in years" :key="year" :value="year">{{ year }}년</option> |
|
15 | 12 |
</select> |
16 |
- <select name="" id="" class="form-select"> |
|
17 |
- <option :value="currentMonth">{{ currentMonth }}월</option> |
|
18 |
- <option value="all">전체</option> |
|
19 |
- <template v-for="month in remainingMonths" :key="month"> |
|
20 |
- <option :value="month" v-if="month !== currentMonth"> {{ month }}월</option> |
|
21 |
- </template> |
|
13 |
+ <select class="form-select" v-model="waitRequest.month" @change="fnChangeCurrentPage(1, 'wait')"> |
|
14 |
+ <option value="">월 전체</option> |
|
15 |
+ <option v-for="month in months" :key="month" :value="month">{{ month }}월</option> |
|
22 | 16 |
</select> |
23 | 17 |
<div class="sch-input"> |
24 | 18 |
<input type="text" class="form-control" placeholder="신청자명"> |
... | ... | @@ -31,11 +25,11 @@ |
31 | 25 |
<div class="tbl-wrap"> |
32 | 26 |
<table id="myTable" class="tbl data"> |
33 | 27 |
<colgroup> |
34 |
- <col style="width: 13%;"> |
|
35 |
- <col style="width: 13%;"> |
|
36 |
- <col style="width: 13%;"> |
|
37 |
- <col style="width: 48%;"> |
|
38 |
- <col style="width: 13%;"> |
|
28 |
+ <col style="width: 13.33%;"> |
|
29 |
+ <col style="width: 13.33%;"> |
|
30 |
+ <col style="width: 13.33%;"> |
|
31 |
+ <col style="width: 30%;"> |
|
32 |
+ <col style="width: 30%;"> |
|
39 | 33 |
</colgroup> |
40 | 34 |
<thead> |
41 | 35 |
<tr> |
... | ... | @@ -47,12 +41,12 @@ |
47 | 41 |
</tr> |
48 | 42 |
</thead> |
49 | 43 |
<tbody> |
50 |
- <tr v-for="(item, idx) in waitListData" :key="idx" :class="{ 'expired': true }"> |
|
51 |
- <td>{{ getCodeName('type', item.iemInfo.vcatnKnd) }}</td> |
|
52 |
- <td>{{ getCodeName('cate', item.sanctnSe) }}</td> |
|
53 |
- <td>{{ item.registerInfo.userNm }}</td> |
|
54 |
- <td>{{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }} ~ {{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }}</td> |
|
55 |
- <td>{{ item.registerInfo.userNm }}</td> |
|
44 |
+ <tr v-for="(item, idx) in waitList" :key="idx"> |
|
45 |
+ <td>{{ item.sanctnIemNm }}</td> |
|
46 |
+ <td>{{ item.sanctnSeNm }}</td> |
|
47 |
+ <td>{{ item.applcntNm }}</td> |
|
48 |
+ <td>{{ $formattedDates(item) }}</td> |
|
49 |
+ <td>{{ item.rgsde }}</td> |
|
56 | 50 |
</tr> |
57 | 51 |
</tbody> |
58 | 52 |
</table> |
... | ... | @@ -61,19 +55,13 @@ |
61 | 55 |
<div class="sch-form-wrap title-wrap"> |
62 | 56 |
<h3><img :src="h3icon" alt="">승인 이력</h3> |
63 | 57 |
<div class="input-group"> |
64 |
- <select name="" id="" class="form-select"> |
|
65 |
- <option :value="currentYear">{{ currentYear }}년</option> |
|
66 |
- <option value="all">전체</option> |
|
67 |
- <template v-for="year in remainingYears" :key="year"> |
|
68 |
- <option :value="year" v-if="year !== currentYear"> {{ year }}년 </option> |
|
69 |
- </template> |
|
58 |
+ <select class="form-select" v-model="confmRequest.year" @change="fnChangeCurrentPage(1, 'wait')"> |
|
59 |
+ <option value="">연도 전체</option> |
|
60 |
+ <option v-for="year in years" :key="year" :value="year">{{ year }}년</option> |
|
70 | 61 |
</select> |
71 |
- <select name="" id="" class="form-select"> |
|
72 |
- <option :value="currentMonth">{{ currentMonth }}월</option> |
|
73 |
- <option value="all">전체</option> |
|
74 |
- <template v-for="month in remainingMonths" :key="month"> |
|
75 |
- <option :value="month" v-if="month !== currentMonth"> {{ month }}월 </option> |
|
76 |
- </template> |
|
62 |
+ <select class="form-select" v-model="confmRequest.month" @change="fnChangeCurrentPage(1, 'wait')"> |
|
63 |
+ <option value="">월 전체</option> |
|
64 |
+ <option v-for="month in months" :key="month" :value="month">{{ month }}월</option> |
|
77 | 65 |
</select> |
78 | 66 |
<select name="" id="" class="form-select"> |
79 | 67 |
<option value="all">상태</option> |
... | ... | @@ -91,12 +79,12 @@ |
91 | 79 |
<div class="tbl-wrap"> |
92 | 80 |
<table id="myTable" class="tbl data"> |
93 | 81 |
<colgroup> |
94 |
- <col style="width: 13%;"> |
|
95 |
- <col style="width: 13%;"> |
|
96 |
- <col style="width: 13%;"> |
|
97 |
- <col style="width: 35%;"> |
|
98 |
- <col style="width: 13%;"> |
|
99 |
- <col style="width: 13%;"> |
|
82 |
+ <col style="width: 13.33%;"> |
|
83 |
+ <col style="width: 13.33%;"> |
|
84 |
+ <col style="width: 13.33%;"> |
|
85 |
+ <col style="width: 30%;"> |
|
86 |
+ <col style="width: 16.66%;"> |
|
87 |
+ <col style="width: 13.33%;"> |
|
100 | 88 |
</colgroup> |
101 | 89 |
<thead> |
102 | 90 |
<tr> |
... | ... | @@ -109,13 +97,13 @@ |
109 | 97 |
</tr> |
110 | 98 |
</thead> |
111 | 99 |
<tbody> |
112 |
- <tr v-for="(item, index) in confmListData" :key="index" :class="{ 'expired': true }"> |
|
113 |
- <td>{{ getCodeName('type', item.iemInfo.vcatnKnd) }}</td> |
|
114 |
- <td>{{ getCodeName('cate', item.sanctnSe) }}</td> |
|
115 |
- <td>{{ item.registerInfo.userNm }}</td> |
|
116 |
- <td>{{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }} ~ {{ $formattedDate(item.iemInfo.bgnde, item.iemInfo.beginHour, item.iemInfo.beginMnt) }}</td> |
|
117 |
- <td>{{ item.registerInfo.userNm }}</td> |
|
118 |
- <td :class="getStatusClass(item.status)">{{ getCodeName('confm', item.confmAt) }}</td> |
|
100 |
+ <tr v-for="(item, index) in confmList" :key="index" :class="{ 'expired': true }"> |
|
101 |
+ <td>{{ item.sanctnIemNm }}</td> |
|
102 |
+ <td>{{ item.sanctnSeNm }}</td> |
|
103 |
+ <td>{{ item.applcntNm }}</td> |
|
104 |
+ <td>{{ $formattedDates(item) }}</td> |
|
105 |
+ <td>{{ item.rgsde }}</td> |
|
106 |
+ <td>{{ item.confmAtNm }}</td> |
|
119 | 107 |
</tr> |
120 | 108 |
</tbody> |
121 | 109 |
</table> |
... | ... | @@ -131,9 +119,6 @@ |
131 | 119 |
// API |
132 | 120 |
import { findSanctnsProc } from '../../../../resources/api/sanctns'; |
133 | 121 |
|
134 |
-const currentYear = new Date().getFullYear(); |
|
135 |
-const currentMonth = new Date().getMonth() + 1; |
|
136 |
- |
|
137 | 122 |
export default { |
138 | 123 |
components: { |
139 | 124 |
SearchOutlined, |
... | ... | @@ -145,33 +130,30 @@ |
145 | 130 |
photoicon: "/client/resources/img/photo_icon.png", |
146 | 131 |
h3icon: "/client/resources/img/h3icon.png", |
147 | 132 |
|
148 |
- // 목록 조회용 |
|
149 |
- waitListData: [], |
|
150 |
- waitRequest: { |
|
151 |
- sanctnDe: null, // 결재일 |
|
152 |
- sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드) |
|
153 |
- sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디 |
|
154 |
- }, |
|
155 |
- confmListData: [], |
|
156 |
- confmRequest: { |
|
157 |
- sanctnDe: null, // 결재일 |
|
158 |
- sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드) |
|
159 |
- sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디 |
|
160 |
- }, |
|
161 |
- |
|
162 |
- currentMonth, |
|
163 |
- selectedMonth: currentMonth, |
|
164 |
- remainingMonths: Array.from({ length: 12 }, (_, i) => i + 1), |
|
165 |
- currentYear, |
|
166 |
- selectedYear: currentYear, |
|
167 |
- remainingYears: Array.from({ length: 10 }, (_, i) => currentYear - i), |
|
168 |
- currentPage: 1, |
|
169 |
- totalPages: 3, |
|
170 |
- // 데이터 초기화 |
|
171 | 133 |
years: [2023, 2024, 2025], // 연도 목록 |
172 | 134 |
months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록 |
173 |
- selectedYear: '', |
|
174 |
- selectedMonth: '', |
|
135 |
+ |
|
136 |
+ // 목록 조회용 |
|
137 |
+ waitList: [], |
|
138 |
+ waitRequest: { |
|
139 |
+ year: '', |
|
140 |
+ month: '', |
|
141 |
+ sanctnDe: null, // 결재일 |
|
142 |
+ sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드) |
|
143 |
+ sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디 |
|
144 |
+ confmAts: "W", // 승인여부 |
|
145 |
+ confmerId: this.$store.state.userInfo.userId, |
|
146 |
+ }, |
|
147 |
+ confmList: [], |
|
148 |
+ confmRequest: { |
|
149 |
+ year: '', |
|
150 |
+ month: '', |
|
151 |
+ sanctnDe: null, // 결재일 |
|
152 |
+ sanctnIem: null, // 결재항목 : 출장 구분 or 휴가 종류 (휴가/출장 구분 코드) |
|
153 |
+ sanctnMbyId: null, // 결재 주체 아이디 : 휴가/출장 아이디 |
|
154 |
+ confmAts: "A,R", // 승인여부 |
|
155 |
+ confmerId: this.$store.state.userInfo.userId, |
|
156 |
+ }, |
|
175 | 157 |
|
176 | 158 |
// 공통코드 목록 |
177 | 159 |
sanctnCodes: [], // 결재 종류 코드 목록 |
... | ... | @@ -182,12 +164,7 @@ |
182 | 164 |
|
183 | 165 |
computed: {}, |
184 | 166 |
|
185 |
- created() { |
|
186 |
- this.initializeSanctnCodes(); |
|
187 |
- |
|
188 |
- console.log("sanctnCodes: ", this.sanctnCodes); |
|
189 |
- console.log("sanctnMbyCodes: ", this.sanctnMbyCodes); |
|
190 |
- }, |
|
167 |
+ created() { }, |
|
191 | 168 |
|
192 | 169 |
mounted() { |
193 | 170 |
this.findList('wait'); // 목록 조회 |
... | ... | @@ -195,84 +172,6 @@ |
195 | 172 |
}, |
196 | 173 |
|
197 | 174 |
methods: { |
198 |
- // 결재 관련 코드 초기화 |
|
199 |
- async initializeSanctnCodes() { |
|
200 |
- try { |
|
201 |
- this.sanctnCodes = []; |
|
202 |
- this.sanctnMbyCodes = []; |
|
203 |
- |
|
204 |
- // 순차적으로 코드 조회 및 추가 |
|
205 |
- const vcatnCodes = await this.findCodeByDepth2('sanctn_mby_vcatn'); // 휴가 종류 |
|
206 |
- this.sanctnCodes.push(...vcatnCodes); |
|
207 |
- |
|
208 |
- const bsrpCodes = await this.findCodeByDepth1('sanctn_mby_bsrp'); // 출장 종류 |
|
209 |
- this.sanctnCodes.push(...bsrpCodes); |
|
210 |
- |
|
211 |
- const sanctnCodes = await this.findCodeByDepth1('sanctn_code'); // 결재 구분 |
|
212 |
- this.sanctnMbyCodes.push(...sanctnCodes); |
|
213 |
- |
|
214 |
- const confmCodes = await this.findCodeByDepth1('confm_code'); // 상태 코드 |
|
215 |
- this.sanctnConfmCodes.push(...confmCodes); |
|
216 |
- } catch (error) { |
|
217 |
- console.error('코드 조회 중 오류 발생:', error); |
|
218 |
- } |
|
219 |
- }, |
|
220 |
- |
|
221 |
- // 코드 목록 조회 (depth 1) |
|
222 |
- async findCodeByDepth1(upperCode) { |
|
223 |
- try { |
|
224 |
- const searchRequest = { |
|
225 |
- searchType: 'upperCd', |
|
226 |
- searchText: upperCode, |
|
227 |
- }; |
|
228 |
- |
|
229 |
- const codes = await this.$findCodeList(searchRequest); |
|
230 |
- return Array.isArray(codes) ? codes : []; |
|
231 |
- |
|
232 |
- } catch (error) { |
|
233 |
- console.error(`코드 조회 실패 (${upperCode}):`, error); |
|
234 |
- return []; |
|
235 |
- } |
|
236 |
- }, |
|
237 |
- |
|
238 |
- // 코드 목록 조회 (depth 2) |
|
239 |
- async findCodeByDepth2(upperCode) { |
|
240 |
- try { |
|
241 |
- const parentCodes = await this.findCodeByDepth1(upperCode); |
|
242 |
- const childCodes = []; |
|
243 |
- |
|
244 |
- for (const code of parentCodes) { |
|
245 |
- const result = await this.findCodeByDepth1(code.code); |
|
246 |
- childCodes.push(...result); |
|
247 |
- } |
|
248 |
- |
|
249 |
- return childCodes; |
|
250 |
- |
|
251 |
- } catch (error) { |
|
252 |
- console.error(`하위 코드 조회 실패 (${upperCode}):`, error); |
|
253 |
- return []; |
|
254 |
- } |
|
255 |
- }, |
|
256 |
- |
|
257 |
- // 코드 매핑 |
|
258 |
- getCodeName(type, code) { |
|
259 |
- let codeList; |
|
260 |
- |
|
261 |
- if (type === 'type') { |
|
262 |
- codeList = this.sanctnCodes; |
|
263 |
- } else if (type === 'cate') { |
|
264 |
- codeList = this.sanctnMbyCodes; |
|
265 |
- } else if (type === 'confm') { |
|
266 |
- const foundCode = this.sanctnConfmCodes?.find(item => item.codeValue === code); |
|
267 |
- return foundCode ? foundCode.codeNm : code; |
|
268 |
- } else { |
|
269 |
- return code; // 알 수 없는 타입이면 원본 반환 |
|
270 |
- } |
|
271 |
- |
|
272 |
- const foundCode = codeList?.find(item => item.code === code); |
|
273 |
- return foundCode ? foundCode.codeNm : code; |
|
274 |
- }, |
|
275 |
- |
|
276 | 175 |
// 목록 조회 |
277 | 176 |
async findList(type) { |
278 | 177 |
const vm = this; |
... | ... | @@ -289,10 +188,10 @@ |
289 | 188 |
const result = response.data.data; |
290 | 189 |
|
291 | 190 |
if (type === 'wait') { |
292 |
- vm.waitListData = result.lists; |
|
191 |
+ vm.waitList = result.lists; |
|
293 | 192 |
vm.waitRequest = result.search; |
294 | 193 |
} else if (type == 'confm') { |
295 |
- vm.confmListData = result.lists; |
|
194 |
+ vm.confmList = result.lists; |
|
296 | 195 |
vm.confmRequest = result.search; |
297 | 196 |
} |
298 | 197 |
} catch (error) { |
... | ... | @@ -316,34 +215,6 @@ |
316 | 215 |
this.$nextTick(() => { |
317 | 216 |
this.findList(type); |
318 | 217 |
}); |
319 |
- }, |
|
320 |
- |
|
321 |
- async onClickSubmit() { |
|
322 |
- // `useMutation` 훅을 사용하여 mutation 함수 가져오기 |
|
323 |
- const { mutate, onDone, onError } = useMutation(mygql); |
|
324 |
- |
|
325 |
- try { |
|
326 |
- const result = await mutate(); |
|
327 |
- console.log(result); |
|
328 |
- } catch (error) { |
|
329 |
- console.error('Mutation error:', error); |
|
330 |
- } |
|
331 |
- }, |
|
332 |
- registerLeave() { |
|
333 |
- console.log("등록 버튼 클릭됨"); |
|
334 |
- |
|
335 |
- // Vue의 반응성 문제를 피하기 위해, 새로운 객체를 추가합니다. |
|
336 |
- this.DeptData = [ |
|
337 |
- ...this.DeptData, |
|
338 |
- { member: '', deptNM: '', acceptTerms: false } |
|
339 |
- ]; |
|
340 |
- |
|
341 |
- console.log(this.DeptData); // 배열 상태 출력 |
|
342 |
- }, |
|
343 |
- getStatusClass(status) { |
|
344 |
- if (status === '승인') return 'status-approved'; |
|
345 |
- if (status === '대기') return 'status-pending'; |
|
346 |
- return ''; |
|
347 | 218 |
}, |
348 | 219 |
}, |
349 | 220 |
}; |
--- client/views/pages/Manager/approval/approvalRequest.vue
+++ client/views/pages/Manager/approval/approvalRequest.vue
... | ... | @@ -5,29 +5,13 @@ |
5 | 5 |
<h2 class="card-title">결재 요청</h2> |
6 | 6 |
<div class="sch-form-wrap"> |
7 | 7 |
<div class="input-group"> |
8 |
- <select name="" id="" class="form-select"> |
|
9 |
- <option :value="currentYear">{{ currentYear }}년</option> |
|
10 |
- <option value="all">전체</option> |
|
11 |
- <option |
|
12 |
- v-for="year in remainingYears" |
|
13 |
- :key="year" |
|
14 |
- :value="year" |
|
15 |
- v-if="year !== currentYear" |
|
16 |
- > |
|
17 |
- {{ year }}년 |
|
18 |
- </option> |
|
8 |
+ <select class="form-select" v-model="request.year" @change="fnChangeCurrentPage(1)"> |
|
9 |
+ <option value="">연도 전체</option> |
|
10 |
+ <option v-for="year in years" :key="year" :value="year">{{ year }}년</option> |
|
19 | 11 |
</select> |
20 |
- <select name="" id="" class="form-select"> |
|
21 |
- <option :value="currentMonth">{{ currentMonth }}월</option> |
|
22 |
- <option value="all">전체</option> |
|
23 |
- <option |
|
24 |
- v-for="month in remainingMonths" |
|
25 |
- :key="month" |
|
26 |
- :value="month" |
|
27 |
- v-if="month !== currentMonth" |
|
28 |
- > |
|
29 |
- {{ month }}월 |
|
30 |
- </option> |
|
12 |
+ <select class="form-select" v-model="request.month" @change="fnChangeCurrentPage(1)"> |
|
13 |
+ <option value="">월 전체</option> |
|
14 |
+ <option v-for="month in months" :key="month" :value="month">{{ month }}월</option> |
|
31 | 15 |
</select> |
32 | 16 |
<select name="" id="" class="form-select"> |
33 | 17 |
<option value="" selected>전체</option> |
... | ... | @@ -42,14 +26,19 @@ |
42 | 26 |
</select> |
43 | 27 |
</div> |
44 | 28 |
</div> |
45 |
- |
|
46 |
- <!-- Table --> |
|
47 | 29 |
<div class="tbl-wrap"> |
48 | 30 |
<table id="myTable" class="tbl data"> |
49 |
- <!-- 동적으로 <th> 생성 --> |
|
31 |
+ <colgroup> |
|
32 |
+ <col style="width: 13.33%;"> |
|
33 |
+ <col style="width: 13.33%;"> |
|
34 |
+ <col style="width: 13.33%;"> |
|
35 |
+ <col style="width: 30%;"> |
|
36 |
+ <col style="width: 16.66%;"> |
|
37 |
+ <col style="width: 13.33%;"> |
|
38 |
+ </colgroup> |
|
50 | 39 |
<thead> |
51 | 40 |
<tr> |
52 |
- <th>구분 </th> |
|
41 |
+ <th>구분</th> |
|
53 | 42 |
<th>결재구분</th> |
54 | 43 |
<th>신청자</th> |
55 | 44 |
<th>기간</th> |
... | ... | @@ -57,162 +46,115 @@ |
57 | 46 |
<th>상태</th> |
58 | 47 |
</tr> |
59 | 48 |
</thead> |
60 |
- <!-- 동적으로 <td> 생성 --> |
|
61 | 49 |
<tbody> |
62 |
- <tr v-for="(item, index) in listData" :key="index" :class="{ 'expired': isPastPeriod(item.period) }"> |
|
63 |
- <td>{{ item.type }}</td> |
|
64 |
- <td>{{ item.approvalType }}</td> |
|
65 |
- <td>{{ item.applicant }}</td> |
|
66 |
- <td>{{ item.period }}</td> |
|
67 |
- <td>{{ item.requestDate }}</td> |
|
68 |
- <td :class="getStatusClass(item.status)">{{ item.status }}</td> |
|
50 |
+ <tr v-for="(item, idx) of lists" :key="idx"> |
|
51 |
+ <td>{{ item.sanctnIemNm }}</td> |
|
52 |
+ <td>{{ item.sanctnSeNm }}</td> |
|
53 |
+ <td>{{ item.applcntNm }}</td> |
|
54 |
+ <td>{{ $formattedDates(item) }}</td> |
|
55 |
+ <td>{{ item.rgsde }}</td> |
|
56 |
+ <td>{{ item.confmAtNm }}</td> |
|
69 | 57 |
</tr> |
70 | 58 |
</tbody> |
71 | 59 |
</table> |
72 |
- |
|
73 | 60 |
</div> |
74 |
- <div class="pagination"> |
|
75 |
- <ul> |
|
76 |
- <!-- 왼쪽 화살표 (이전 페이지) --> |
|
77 |
- <li class="arrow" :class="{ disabled: currentPage === 1 }" @click="changePage(currentPage - 1)"> |
|
78 |
- < |
|
79 |
- </li> |
|
80 |
- |
|
81 |
- <!-- 페이지 번호 --> |
|
82 |
- <li v-for="page in totalPages" :key="page" :class="{ active: currentPage === page }" |
|
83 |
- @click="changePage(page)"> |
|
84 |
- {{ page }} |
|
85 |
- </li> |
|
86 |
- |
|
87 |
- <!-- 오른쪽 화살표 (다음 페이지) --> |
|
88 |
- <li class="arrow" :class="{ disabled: currentPage === totalPages }" @click="changePage(currentPage + 1)"> |
|
89 |
- > |
|
90 |
- </li> |
|
91 |
- </ul> |
|
92 |
- </div> |
|
93 |
- <!-- End Table --> |
|
61 |
+ <Pagenation :search="request" @onChange="fnChangeCurrentPage" /> |
|
94 | 62 |
<div class="buttons"> |
95 |
- <button type="button" class="btn sm primary" @click="showOptions = true"> |
|
96 |
- 등록 |
|
97 |
- </button> |
|
98 |
- |
|
99 |
- <!-- 신청 종류 선택 모달 --> |
|
100 |
- <div v-if="showOptions" class="popup-overlay"> |
|
101 |
- <div class="popup-content"> |
|
102 |
- <div class="card"> |
|
103 |
- <div class="card-body"> |
|
104 |
- <h2 class="card-title">신청종류선택</h2> |
|
105 |
- <div class="buttons"> |
|
106 |
- <button class="btn hyuga" @click="goToPage('휴가')">휴가신청</button> |
|
107 |
- <button class="btn chuljang" @click="goToPage('출장')">출장신청</button> |
|
108 |
- </div> |
|
109 |
- </div> |
|
110 |
- </div> |
|
111 |
- <button class="close-btn" @click="showOptions = false"> <CloseCircleFilled /></button> |
|
112 |
- </div> |
|
113 |
- |
|
114 |
- </div> |
|
63 |
+ <button type="button" class="btn sm primary" @click="showOptions = true"> 등록 </button> |
|
115 | 64 |
</div> |
116 | 65 |
</div> |
117 | 66 |
</div> |
118 | 67 |
</div> |
68 |
+ <div v-if="showOptions" class="popup-overlay"> |
|
69 |
+ <div class="popup-content"> |
|
70 |
+ <div class="card"> |
|
71 |
+ <div class="card-body"> |
|
72 |
+ <h2 class="card-title">신청종류선택</h2> |
|
73 |
+ <div class="buttons"> |
|
74 |
+ <button class="btn hyuga" @click="goToPage('휴가')">휴가신청</button> |
|
75 |
+ <button class="btn chuljang" @click="goToPage('출장')">출장신청</button> |
|
76 |
+ </div> |
|
77 |
+ </div> |
|
78 |
+ </div> |
|
79 |
+ <button class="close-btn" @click="showOptions = false"> |
|
80 |
+ <CloseCircleFilled /> |
|
81 |
+ </button> |
|
82 |
+ </div> |
|
83 |
+ </div> |
|
119 | 84 |
</template> |
120 |
- |
|
121 | 85 |
<script> |
122 |
-import { ref } from 'vue'; |
|
123 | 86 |
import { SearchOutlined, CloseCircleFilled } from '@ant-design/icons-vue'; |
124 |
-const currentYear = new Date().getFullYear(); |
|
125 |
-const currentMonth = new Date().getMonth() + 1; |
|
87 |
+import Pagenation from '../../../component/Pagenation.vue'; |
|
88 |
+// API |
|
89 |
+import { findSanctnsProc } from '../../../../resources/api/sanctns'; |
|
90 |
+ |
|
126 | 91 |
export default { |
92 |
+ components: { |
|
93 |
+ SearchOutlined, CloseCircleFilled, |
|
94 |
+ Pagenation, |
|
95 |
+ }, |
|
96 |
+ |
|
127 | 97 |
data() { |
128 | 98 |
return { |
129 |
- currentMonth, |
|
130 |
- selectedMonth: currentMonth, |
|
131 |
- remainingMonths: Array.from({ length: 12 }, (_, i) => i + 1), |
|
132 |
- currentYear, |
|
133 |
- selectedYear: currentYear, |
|
134 |
- remainingYears: Array.from({ length: 10 }, (_, i) => currentYear - i), |
|
135 |
- showOptions: false, |
|
136 |
- currentPage: 1, |
|
137 |
- totalPages: 3, |
|
138 | 99 |
photoicon: "/client/resources/img/photo_icon.png", |
139 |
- // 데이터 초기화 |
|
140 |
- years: [2023, 2024, 2025], // 연도 목록 |
|
141 |
- months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 월 목록 |
|
142 |
- selectedYear: '', |
|
143 |
- selectedMonth: '', |
|
144 |
- listData: [ |
|
145 |
- { |
|
146 |
- type: '연차', |
|
147 |
- approvalType: '결재', |
|
148 |
- applicant: '홍길동', |
|
149 |
- period: '2025-05-10 ~ 2025-15-03', |
|
150 |
- requestDate: '2025-04-25', |
|
151 |
- status: '대기' |
|
152 |
- }, { |
|
153 |
- type: '반차', |
|
154 |
- approvalType: '전결', |
|
155 |
- applicant: '홍길동', |
|
156 |
- period: '2025-05-01 ~ 2025-05-03', |
|
157 |
- requestDate: '2025-04-25', |
|
158 |
- status: '승인' |
|
159 |
- }], |
|
160 |
- filteredData: [], |
|
100 |
+ showOptions: false, |
|
101 |
+ |
|
102 |
+ years: [], |
|
103 |
+ months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], |
|
104 |
+ |
|
105 |
+ lists: [], |
|
106 |
+ request: { |
|
107 |
+ year: '', |
|
108 |
+ month: '', |
|
109 |
+ register: this.$store.state.userInfo.userId, |
|
110 |
+ }, |
|
161 | 111 |
}; |
162 | 112 |
}, |
163 |
- components: { |
|
164 |
- SearchOutlined, CloseCircleFilled |
|
165 |
- }, |
|
166 |
- computed: { |
|
167 |
- }, |
|
168 |
- methods: { |
|
169 |
- changePage(page) { |
|
170 |
- if (page < 1 || page > this.totalPages) return; |
|
171 |
- this.currentPage = page; |
|
172 |
- this.$emit('page-changed', page); // 필요 시 부모에 알림 |
|
173 |
- }, |
|
174 |
- async onClickSubmit() { |
|
175 |
- // `useMutation` 훅을 사용하여 mutation 함수 가져오기 |
|
176 |
- const { mutate, onDone, onError } = useMutation(mygql); |
|
177 | 113 |
|
178 |
- try { |
|
179 |
- const result = await mutate(); |
|
180 |
- console.log(result); |
|
181 |
- } catch (error) { |
|
182 |
- console.error('Mutation error:', error); |
|
183 |
- } |
|
184 |
- }, |
|
185 |
- goToPage(type) { |
|
186 |
- if (type === '휴가') { |
|
187 |
- this.$router.push({ name: 'HyugaInsert' }); |
|
188 |
- } else if (type === '출장') { |
|
189 |
- this.$router.push({ name: 'HyugaChuljangDetailDetail' }); |
|
190 |
- } |
|
191 |
- }, |
|
192 |
- getStatusClass(status) { |
|
193 |
- if (status === '승인') return 'status-approved'; |
|
194 |
- if (status === '대기') return 'status-pending'; |
|
195 |
- return ''; |
|
196 |
- }, |
|
197 |
- isPastPeriod(period) { |
|
198 |
- // 예: '2025-05-01 ~ 2025-05-03' → 종료일 추출 |
|
199 |
- const endDateStr = period.split('~')[1]?.trim(); |
|
200 |
- if (!endDateStr) return false; |
|
201 |
- |
|
202 |
- const endDate = new Date(endDateStr); |
|
203 |
- const today = new Date(); |
|
204 |
- |
|
205 |
- // 현재 날짜보다 과거면 true |
|
206 |
- return endDate < today; |
|
207 |
- } |
|
208 |
- }, |
|
209 | 114 |
created() { |
115 |
+ this.generateYears(); |
|
210 | 116 |
}, |
117 |
+ |
|
211 | 118 |
mounted() { |
119 |
+ this.findList(); // 목록 조회 |
|
120 |
+ }, |
|
212 | 121 |
|
122 |
+ methods: { |
|
123 |
+ generateYears() { |
|
124 |
+ const startYear = 2020; |
|
125 |
+ const currentYear = new Date().getFullYear(); |
|
213 | 126 |
|
127 |
+ for (let year = currentYear; year >= startYear; year--) { |
|
128 |
+ this.years.push(year); |
|
129 |
+ } |
|
130 |
+ }, |
|
131 |
+ |
|
132 |
+ // 목록 조회 |
|
133 |
+ async findList() { |
|
134 |
+ const vm = this; |
|
135 |
+ try { |
|
136 |
+ const response = await findSanctnsProc(vm.request); |
|
137 |
+ const result = response.data.data; |
|
138 |
+ |
|
139 |
+ this.lists = result.lists; |
|
140 |
+ this.request = result.search; |
|
141 |
+ } catch (error) { |
|
142 |
+ if (error.response) { |
|
143 |
+ alert(error.response.data.message); |
|
144 |
+ } else { |
|
145 |
+ alert("에러가 발생했습니다."); |
|
146 |
+ } |
|
147 |
+ console.error(error.message); |
|
148 |
+ }; |
|
149 |
+ }, |
|
150 |
+ |
|
151 |
+ // 페이지 이동 |
|
152 |
+ fnChangeCurrentPage(currentPage) { |
|
153 |
+ this.request.currentPage = Number(currentPage); |
|
154 |
+ this.$nextTick(() => { |
|
155 |
+ this.findList(); |
|
156 |
+ }); |
|
157 |
+ }, |
|
214 | 158 |
}, |
215 | 159 |
}; |
216 |
-</script> |
|
217 |
- |
|
218 |
-<style scoped></style> |
|
160 |
+</script>(파일 끝에 줄바꿈 문자 없음) |
--- client/views/pages/Manager/asset/asset.vue
+++ client/views/pages/Manager/asset/asset.vue
... | ... | @@ -155,7 +155,6 @@ |
155 | 155 |
created() { |
156 | 156 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
157 | 157 |
const storedData = localStorage.getItem('DeptData'); |
158 |
- console.log(storedData); |
|
159 | 158 |
if (storedData) { |
160 | 159 |
this.DeptData = JSON.parse(storedData); |
161 | 160 |
} |
--- client/views/pages/Manager/attendance/HyugaDetail.vue
+++ client/views/pages/Manager/attendance/HyugaDetail.vue
... | ... | @@ -4,71 +4,48 @@ |
4 | 4 |
<h2 class="card-title">휴가 현황</h2> |
5 | 5 |
<div class="form-card"> |
6 | 6 |
<h1>휴가신청서</h1> |
7 |
- <div v-if="detailData.sanctnList && detailData.sanctnList.length > 0" class="approval-box tbl-wrap tbl2"> |
|
8 |
- <table class="tbl data"> |
|
9 |
- <tbody> |
|
10 |
- <tr class="thead"> |
|
11 |
- <td rowspan="2" class="th">승인자</td> |
|
12 |
- <template v-for="(item, idx) of detailData.sanctnList" :key="idx"> |
|
13 |
- <td>{{ fnFindNm(item.clsf) }}</td> |
|
14 |
- </template> |
|
15 |
- </tr> |
|
16 |
- <tr> |
|
17 |
- <td v-for="(item, idx) of detailData.sanctnList" :key="idx"> |
|
18 |
- <template v-if="item.confmAt === 'A'"> |
|
19 |
- <p v-if="item.sanctnSe === 'sanctn_agncy'">(대결)</p> |
|
20 |
- <p class="name">{{ item.confmerInfo?.userNm || '' }}</p> |
|
21 |
- <small class="date">{{ new Date(item.sanctnDe).toISOString().split('T')[0] }}</small> |
|
22 |
- </template> |
|
23 |
- <template v-else-if="item.confmAt === 'R'"> |
|
24 |
- <p class="name">반려</p> |
|
25 |
- </template> |
|
26 |
- </td> |
|
27 |
- </tr> |
|
28 |
- </tbody> |
|
29 |
- </table> |
|
30 |
- </div> |
|
7 |
+ <SanctnViewList v-if="detailData.sanctnList.length > 0" :sanctns="detailData.sanctnList" /> |
|
31 | 8 |
<form class="row g-3 needs-validation detail" novalidate> |
32 | 9 |
<div class="col-12"> |
33 | 10 |
<div class="col-12 border-x"> |
34 | 11 |
<label for="vcatnType" class="form-label">유형</label> |
35 |
- <p>{{ formattedVcatnKnd }}</p> |
|
12 |
+ <p>{{ detailData.vcatnKndNm }}</p> |
|
36 | 13 |
</div> |
37 | 14 |
<div class="col-12 border-x"> |
38 | 15 |
<label for="applicant" class="form-label">신청자</label> |
39 |
- <p>{{ detailData.registerInfo?.userNm || '' }}</p> |
|
16 |
+ <p>{{ detailData.userNm }}</p> |
|
40 | 17 |
</div> |
41 | 18 |
</div> |
42 | 19 |
<div class="col-12"> |
43 | 20 |
<div class="col-12 border-x"> |
44 | 21 |
<label for="department" class="form-label">부서</label> |
45 |
- <p>{{ detailData.registerInfo?.userDeptInfo?.deptVO?.deptNm || '' }}</p> |
|
22 |
+ <p>{{ detailData.deptNm }}</p> |
|
46 | 23 |
</div> |
47 | 24 |
<div class="col-12 border-x"> |
48 | 25 |
<label for="position" class="form-label">직급</label> |
49 |
- <p>{{ formattedClsf }}</p> |
|
26 |
+ <p>{{ detailData.clsfNm }}</p> |
|
50 | 27 |
</div> |
51 | 28 |
</div> |
52 | 29 |
<div class="col-12"> |
53 | 30 |
<label for="period" class="form-label">기간</label> |
54 |
- <p>{{ formattedPeriod }}</p> |
|
31 |
+ <p>{{ $formattedDates(detailData) }}</p> |
|
55 | 32 |
</div> |
56 | 33 |
<div class="col-12 hyuga"> |
57 | 34 |
<label for="details" class="form-label">세부사항</label> |
58 |
- <ViewerComponent :content="detailData.detailCn || ''" /> |
|
35 |
+ <ViewerComponent :content="detailData.detailCn" /> |
|
59 | 36 |
</div> |
60 | 37 |
<div class="col-12"> |
61 | 38 |
<label for="requestDate" class="form-label">신청일</label> |
62 |
- <p>{{ detailData.rgsde || '' }}</p> |
|
39 |
+ <p>{{ detailData.rgsde }}</p> |
|
63 | 40 |
</div> |
64 | 41 |
<div class="col-12"> |
65 | 42 |
<label for="status" class="form-label">상태</label> |
66 |
- <p>{{ formattedStatus }}</p> |
|
43 |
+ <p>{{ detailData.confmAtNm }}</p> |
|
67 | 44 |
</div> |
68 | 45 |
<div v-if="detailData.confmAt === 'R'" class="col-12 border-x return"> |
69 | 46 |
<label for="rejectReason" class="form-label">반려사유</label> |
70 | 47 |
<template v-for="(item, idx) of detailData.sanctnList" :key="idx"> |
71 |
- <p v-if="item.confmAt === 'R'">{{ item.returnResn || '' }}</p> |
|
48 |
+ <p v-if="item.confmAt === 'R'">{{ item.returnResn }}</p> |
|
72 | 49 |
</template> |
73 | 50 |
</div> |
74 | 51 |
</form> |
... | ... | @@ -86,77 +63,53 @@ |
86 | 63 |
<script> |
87 | 64 |
import ReturnPopup from '../../../component/Popup/ReturnPopup.vue'; |
88 | 65 |
import ViewerComponent from '../../../component/editor/ViewerComponent.vue'; |
66 |
+import SanctnViewList from '../../../component/Sanctn/SanctnViewList.vue'; |
|
89 | 67 |
// API |
90 | 68 |
import { findVcatnProc, deleteVcatnProc } from '../../../../resources/api/vcatn'; |
91 | 69 |
|
92 | 70 |
export default { |
93 |
- components: { ReturnPopup, ViewerComponent }, |
|
71 |
+ components: { |
|
72 |
+ ReturnPopup, ViewerComponent, |
|
73 |
+ SanctnViewList, |
|
74 |
+ }, |
|
94 | 75 |
|
95 | 76 |
data() { |
96 | 77 |
return { |
97 | 78 |
require: "/client/resources/img/require.png", |
98 | 79 |
|
99 | 80 |
pageId: null, |
100 |
- isRegister: false, |
|
101 | 81 |
showPopup: false, |
82 |
+ isRegister: false, |
|
102 | 83 |
|
103 |
- // 휴가 신청서 정보 |
|
104 | 84 |
detailData: { |
105 |
- registerInfo: {}, |
|
106 |
- sanctnList: [], |
|
107 |
- confmAt: '', |
|
108 |
- vcatnKnd: '', |
|
109 |
- clsf: '', |
|
110 |
- bgnde: '', |
|
111 |
- endde: '', |
|
112 |
- detailCn: '', |
|
113 |
- rgsde: '' |
|
85 |
+ vcatnId: null, |
|
86 |
+ userId: null, |
|
87 |
+ userNm: null, |
|
88 |
+ vcatnKnd: null, |
|
89 |
+ vcatnKndNm: null, |
|
90 |
+ deptId: null, |
|
91 |
+ deptNm: null, |
|
92 |
+ clsf: null, |
|
93 |
+ clsfNm: null, |
|
94 |
+ bgnde: null, |
|
95 |
+ beginHour: null, |
|
96 |
+ beginMnt: null, |
|
97 |
+ endde: null, |
|
98 |
+ endHour: null, |
|
99 |
+ endMnt: null, |
|
100 |
+ detailCn: null, |
|
101 |
+ confmAt: null, |
|
102 |
+ confmAtNm: null, |
|
103 |
+ rgsde: null, |
|
104 |
+ register: null, |
|
105 |
+ updde: null, |
|
106 |
+ updusr: null, |
|
107 |
+ sanctnList: [] |
|
114 | 108 |
}, |
115 |
- |
|
116 |
- cmmnCodes: { |
|
117 |
- vcatnKndCodeList: [], |
|
118 |
- clsfCodeList: [], |
|
119 |
- confmCodeList: [] |
|
120 |
- } |
|
121 | 109 |
}; |
122 | 110 |
}, |
123 | 111 |
|
124 |
- computed: { |
|
125 |
- formattedVcatnKnd() { |
|
126 |
- if (!this.cmmnCodes.vcatnKndCodeList || this.cmmnCodes.vcatnKndCodeList.length === 0) return this.detailData.vcatnKnd; |
|
127 |
- const vcatnKnd = this.cmmnCodes.vcatnKndCodeList.find(v => v.code === this.detailData.vcatnKnd); |
|
128 |
- return vcatnKnd ? vcatnKnd.codeNm : this.detailData.vcatnKnd; |
|
129 |
- }, |
|
130 |
- |
|
131 |
- formattedClsf() { |
|
132 |
- if (!this.cmmnCodes.clsfCodeList || this.cmmnCodes.clsfCodeList.length === 0) return this.detailData.clsf; |
|
133 |
- const clsf = this.cmmnCodes.clsfCodeList.find(v => v.code === this.detailData.clsf); |
|
134 |
- return clsf ? clsf.codeNm : this.detailData.clsf; |
|
135 |
- }, |
|
136 |
- |
|
137 |
- formattedStatus() { |
|
138 |
- if (!this.cmmnCodes.confmCodeList || this.cmmnCodes.confmCodeList.length === 0) return this.detailData.confmAt; |
|
139 |
- const confmAt = this.cmmnCodes.confmCodeList.find(v => v.codeValue === this.detailData.confmAt); |
|
140 |
- return confmAt ? confmAt.codeNm : this.detailData.confmAt; |
|
141 |
- }, |
|
142 |
- |
|
143 |
- formattedPeriod() { |
|
144 |
- if (!this.detailData.bgnde || !this.detailData.endde) return ''; |
|
145 |
- |
|
146 |
- const formattedBgnde = this.detailData.bgnde.split(' ')[0]; |
|
147 |
- const formattedBeginHour = this.detailData.beginHour?.toString().padStart(2, '0') || '00'; |
|
148 |
- const formattedBeginMnt = this.detailData.beginMnt?.toString().padStart(2, '0') || '00'; |
|
149 |
- const startDay = `${formattedBgnde} ${formattedBeginHour}:${formattedBeginMnt}`; |
|
150 |
- |
|
151 |
- const formattedEndde = this.detailData.endde.split(' ')[0]; |
|
152 |
- const formattedEndHour = this.detailData.endHour?.toString().padStart(2, '0') || '00'; |
|
153 |
- const formattedEndMnt = this.detailData.endMnt?.toString().padStart(2, '0') || '00'; |
|
154 |
- const endDay = `${formattedEndde} ${formattedEndHour}:${formattedEndMnt}`; |
|
155 |
- |
|
156 |
- const dayCount = this.calculateDayCount(); |
|
157 |
- return `${startDay} ~ ${endDay} (${dayCount}일)`; |
|
158 |
- }, |
|
159 |
- }, |
|
112 |
+ computed: {}, |
|
160 | 113 |
|
161 | 114 |
async created() { |
162 | 115 |
this.pageId = this.$route.query.id; |
... | ... | @@ -164,9 +117,6 @@ |
164 | 117 |
alert("게시물이 존재하지 않습니다."); |
165 | 118 |
this.fnMoveTo('list'); |
166 | 119 |
} |
167 |
- |
|
168 |
- // 코드 목록 초기화 |
|
169 |
- this.cmmnCodes = await this.$defaultCodes(); |
|
170 | 120 |
}, |
171 | 121 |
|
172 | 122 |
mounted() { |
... | ... | @@ -191,15 +141,6 @@ |
191 | 141 |
console.error(error.message); |
192 | 142 |
this.fnMoveTo('list'); |
193 | 143 |
} |
194 |
- }, |
|
195 |
- |
|
196 |
- fnFindNm(code) { |
|
197 |
- if (this.$isEmpty(code)) { |
|
198 |
- return code; |
|
199 |
- } |
|
200 |
- |
|
201 |
- const clsf = this.cmmnCodes.clsfCodeList.find(v => v.code === code); |
|
202 |
- return clsf ? clsf.codeNm : code; |
|
203 | 144 |
}, |
204 | 145 |
|
205 | 146 |
// 일수 계산 |
--- client/views/pages/Manager/attendance/HyugaInsert.vue
+++ client/views/pages/Manager/attendance/HyugaInsert.vue
... | ... | @@ -10,14 +10,8 @@ |
10 | 10 |
</label> |
11 | 11 |
<select class="form-select" style="max-width: 200px;" v-model="editData.vcatnKnd" @change="fnOnchangeVcatnKnd"> |
12 | 12 |
<option value="" disabled hidden>유형 선택</option> |
13 |
- <option v-for="(item, idx) of cmmnCodes.vcatnKndCodeList" :key="idx" :value="item.code">{{ item.codeNm }}</option> |
|
13 |
+ <option v-for="(item, idx) of vcatnKnds" :key="idx" :value="item.code">{{ item.codeNm }}</option> |
|
14 | 14 |
</select> |
15 |
- <template v-if="showSubTypeSelect"> |
|
16 |
- <select class="form-select mt-2" style="max-width: 200px;" v-model="editData.vcatnSubKnd" @change="fnOnchangeVcatnSubKnd"> |
|
17 |
- <option value="" disabled hidden>세부 유형 선택</option> |
|
18 |
- <option v-for="(item, idx) of subTypes" :key="idx" :value="item.code">{{ item.codeNm }}</option> |
|
19 |
- </select> |
|
20 |
- </template> |
|
21 | 15 |
</div> |
22 | 16 |
<div class="col-12"> |
23 | 17 |
<label for="bgnde" class="form-label"> |
... | ... | @@ -50,9 +44,9 @@ |
50 | 44 |
<PlusCircleFilled /> |
51 | 45 |
</button> |
52 | 46 |
</label> |
53 |
- <HrPopup v-if="isOpenModal && isCodesLoaded" :sanctns="editData.sanctnList" :cmmnCodes="cmmnCodes" @onSelected="fnAddSanctn" @close="isOpenModal = false" /> |
|
47 |
+ <HrPopup v-if="isOpenModal" :lists="editData.sanctnList" @onSelected="fnAddSanctn" @close="isOpenModal = false" /> |
|
54 | 48 |
<div class="approval-container"> |
55 |
- <SanctnList v-model:sanctns="editData.sanctnList" @delSanctn="fnDelSanctn" /> |
|
49 |
+ <SanctnList v-model:lists="editData.sanctnList" @delSanctn="fnDelSanctn" /> |
|
56 | 50 |
</div> |
57 | 51 |
</div> |
58 | 52 |
<div class="col-12 border-x hyuga"> |
... | ... | @@ -90,13 +84,14 @@ |
90 | 84 |
data() { |
91 | 85 |
return { |
92 | 86 |
require: "/client/resources/img/require.png", |
87 |
+ |
|
93 | 88 |
pageId: null, |
94 | 89 |
isOpenModal: false, |
90 |
+ |
|
95 | 91 |
editData: { |
96 | 92 |
vcatnId: null, |
97 | 93 |
userId: null, |
98 |
- vcatnKnd: '', |
|
99 |
- vcatnSubKnd: '', // 세부 유형 추가 |
|
94 |
+ vcatnKnd: null, |
|
100 | 95 |
deptId: null, |
101 | 96 |
clsf: null, |
102 | 97 |
bgnde: null, |
... | ... | @@ -107,49 +102,77 @@ |
107 | 102 |
endMnt: null, |
108 | 103 |
detailCn: null, |
109 | 104 |
confmAt: null, |
110 |
- sanctnList: [], |
|
105 |
+ rgsde: null, |
|
106 |
+ register: null, |
|
107 |
+ updde: null, |
|
108 |
+ updusr: null, |
|
109 |
+ sanctnList: [] |
|
111 | 110 |
}, |
112 | 111 |
dayCnt: 0, |
113 | 112 |
totalDays: 0, |
114 |
- cmmnCodes: {}, |
|
115 | 113 |
workConfig: { |
116 | 114 |
startHour: 9, // 근무 시작 시간 |
117 | 115 |
endHour: 18, // 근무 종료 시간 |
118 | 116 |
lunchStart: 12, // 점심 시작 시간 |
119 | 117 |
lunchEnd: 13, // 점심 종료 시간 |
120 | 118 |
}, |
121 |
- subTypes: [], |
|
119 |
+ |
|
120 |
+ vcatnKnds: [], |
|
121 |
+ halfDaySubTypes: [], |
|
122 |
+ vcatnSubKnd: null, |
|
123 |
+ |
|
124 |
+ sanctnCodes: [], |
|
122 | 125 |
}; |
123 | 126 |
}, |
124 | 127 |
|
125 | 128 |
computed: { |
126 |
- // 세부 유형 선택박스를 보여줄지 여부 |
|
127 | 129 |
showSubTypeSelect() { |
128 |
- return this.dayCnt === 0.5 && this.subTypes.length > 0; |
|
130 |
+ return this.dayCnt === 0.5; |
|
129 | 131 |
}, |
130 | 132 |
|
131 |
- // cmmnCodes가 로드되었는지 확인 |
|
132 |
- isCodesLoaded() { |
|
133 |
- return this.cmmnCodes && Object.keys(this.cmmnCodes).length > 0; |
|
133 |
+ // 현재 선택된 유형이 반차 하위 유형인지 확인 |
|
134 |
+ isHalfDaySubType() { |
|
135 |
+ return this.halfDaySubTypes.some(item => item.code === this.editData.vcatnKnd); |
|
134 | 136 |
} |
135 | 137 |
}, |
136 | 138 |
|
137 | 139 |
async created() { |
138 | 140 |
this.pageId = this.$route.query.id; |
139 |
- this.cmmnCodes = await this.$defaultCodes(); |
|
140 |
- for (const vcatnType of this.cmmnCodes.vcatnKndCodeList) { |
|
141 |
- if (parseFloat(vcatnType.codeValue) === 0.5) { |
|
142 |
- this.subTypes = await this.$findChildCodes(vcatnType.code); |
|
143 |
- break; |
|
141 |
+ |
|
142 |
+ // 휴가 유형 조회 |
|
143 |
+ this.vcatnKnds = []; // 초기화 |
|
144 |
+ let halfDaySubTypes = []; |
|
145 |
+ const vcatnKndCodes = await this.$findChildCodes('sanctn_mby_vcatn'); |
|
146 |
+ for (const code of vcatnKndCodes) { |
|
147 |
+ const childCodes = await this.$findChildCodes(code.code); |
|
148 |
+ for (const childCode of childCodes) { |
|
149 |
+ if (parseFloat(childCode.codeValue) === 0.5) { |
|
150 |
+ // 반차(0.5)인 경우 해당 유형은 제외하고 하위 코드만 추가 |
|
151 |
+ const subTypes = await this.$findChildCodes(childCode.code); |
|
152 |
+ this.vcatnKnds.push(...subTypes); |
|
153 |
+ halfDaySubTypes.push(...subTypes); |
|
154 |
+ } else { |
|
155 |
+ // 반차가 아닌 경우 그대로 추가 |
|
156 |
+ this.vcatnKnds.push(childCode); |
|
157 |
+ } |
|
144 | 158 |
} |
159 |
+ } |
|
160 |
+ this.halfDaySubTypes = halfDaySubTypes; |
|
161 |
+ |
|
162 |
+ if (this.vcatnKnds.length > 0) { |
|
163 |
+ this.editData.vcatnKnd = this.vcatnKnds[0].code; |
|
164 |
+ } |
|
165 |
+ |
|
166 |
+ // 결재 구분 |
|
167 |
+ this.sanctnCodes = await this.$findChildCodes('sanctn_code'); |
|
168 |
+ |
|
169 |
+ // 상세 조회 (pageId가 있는 경우) |
|
170 |
+ if (!this.$isEmpty(this.pageId)) { |
|
171 |
+ await this.findData(); |
|
145 | 172 |
} |
146 | 173 |
}, |
147 | 174 |
|
148 |
- mounted() { |
|
149 |
- if (!this.$isEmpty(this.pageId)) { |
|
150 |
- this.findData(); |
|
151 |
- } |
|
152 |
- }, |
|
175 |
+ mounted() { }, |
|
153 | 176 |
|
154 | 177 |
watch: { |
155 | 178 |
'editData.bgnde'(newVal, oldVal) { |
... | ... | @@ -165,6 +188,7 @@ |
165 | 188 |
}, |
166 | 189 |
|
167 | 190 |
methods: { |
191 |
+ // 상세 조회 |
|
168 | 192 |
async findData() { |
169 | 193 |
try { |
170 | 194 |
const response = await findVcatnProc(this.pageId); |
... | ... | @@ -174,21 +198,9 @@ |
174 | 198 |
this.editData.bgnde = this.editData.bgnde.split(' ')[0]; |
175 | 199 |
this.editData.endde = this.editData.endde.split(' ')[0]; |
176 | 200 |
|
177 |
- let sanctns = []; |
|
178 |
- for (let sanctn of this.editData.sanctnList) { |
|
179 |
- let data = { |
|
180 |
- confmerId: sanctn.confmerId, |
|
181 |
- clsf: sanctn.clsf, |
|
182 |
- sanctnOrdr: sanctn.sanctnOrdr, |
|
183 |
- sanctnSe: sanctn.sanctnSe, |
|
184 |
- clsfNm: sanctn.confmerInfo?.clsf, |
|
185 |
- userNm: sanctn.confmerInfo?.userNm |
|
186 |
- } |
|
187 |
- sanctns.push(data); |
|
188 |
- } |
|
189 |
- this.editData.sanctnList = sanctns; |
|
190 |
- |
|
201 |
+ await this.$nextTick(); |
|
191 | 202 |
await this.fnOnchangeVcatnKnd(); |
203 |
+ |
|
192 | 204 |
} catch (error) { |
193 | 205 |
console.error('데이터 조회 실패:', error); |
194 | 206 |
const message = error.response?.data?.message || "데이터를 불러오는데 실패했습니다."; |
... | ... | @@ -199,23 +211,19 @@ |
199 | 211 |
|
200 | 212 |
// 유형 변경 |
201 | 213 |
async fnOnchangeVcatnKnd() { |
202 |
- if (!this.isCodesLoaded || !Array.isArray(this.cmmnCodes.vcatnKndCodeList)) { |
|
203 |
- console.warn('cmmnCodes가 초기화되지 않았습니다.'); |
|
204 |
- return; |
|
205 |
- } |
|
206 |
- |
|
207 |
- const selectedVcatn = this.cmmnCodes.vcatnKndCodeList.find(item => item.code === this.editData.vcatnKnd); |
|
214 |
+ const selectedVcatn = this.vcatnKnds.find(item => item.code === this.editData.vcatnKnd); |
|
208 | 215 |
if (!selectedVcatn) { |
209 | 216 |
console.warn('선택된 휴가 유형을 찾을 수 없습니다.'); |
210 | 217 |
return; |
211 | 218 |
} |
212 | 219 |
|
213 |
- this.dayCnt = parseFloat(selectedVcatn.codeValue); |
|
214 |
- |
|
215 |
- if (this.dayCnt === 0.5) { |
|
220 |
+ // 반차 하위 유형인지 확인 |
|
221 |
+ if (this.isHalfDaySubType) { |
|
222 |
+ this.dayCnt = 0.5; |
|
223 |
+ this.setHalfDayTime(selectedVcatn); |
|
216 | 224 |
this.changeBgnde(); // 반차일 경우 종료일을 시작일과 동일하게 설정 |
217 | 225 |
} else { |
218 |
- this.editData.vcatnSubKnd = ''; // 세부 유형 선택 초기화 |
|
226 |
+ this.dayCnt = parseFloat(selectedVcatn.codeValue); |
|
219 | 227 |
|
220 | 228 |
// 전체 근무시간으로 설정 |
221 | 229 |
this.editData.beginHour = this.workConfig.startHour.toString().padStart(2, '0'); |
... | ... | @@ -224,17 +232,6 @@ |
224 | 232 |
this.editData.endMnt = '00'; |
225 | 233 |
this.calculateTotalDays(); |
226 | 234 |
} |
227 |
- }, |
|
228 |
- |
|
229 |
- // 세부 유형 변경 |
|
230 |
- fnOnchangeVcatnSubKnd() { |
|
231 |
- if (this.dayCnt === 0.5) { |
|
232 |
- const selectedSubType = this.subTypes.find(item => item.code === this.editData.vcatnSubKnd); |
|
233 |
- if (selectedSubType) { |
|
234 |
- this.setHalfDayTime(selectedSubType); |
|
235 |
- } |
|
236 |
- } |
|
237 |
- this.calculateTotalDays(); |
|
238 | 235 |
}, |
239 | 236 |
|
240 | 237 |
// 반차 시간 설정 메서드 |
... | ... | @@ -359,13 +356,16 @@ |
359 | 356 |
// 승인자 |
360 | 357 |
fnAddSanctn(user) { |
361 | 358 |
const data = { |
362 |
- confmerId: user.userId, |
|
363 |
- clsf: user.clsf, |
|
364 |
- sanctnOrdr: this.editData.nmprList.length + 1, |
|
365 |
- sanctnSe: this.cmmnCodes.sanctnCodeList[0].code, |
|
359 |
+ sanctnId: null, // 결재 아이디 |
|
360 |
+ confmerId: user.userId, // 승인자 아이디 |
|
361 |
+ clsf: user.clsf, // 직급 |
|
362 |
+ sanctnOrdr: this.editData.sanctnList.length + 1, // 결재 순서 |
|
363 |
+ sanctnIem: this.editData.vcatnKnd, // 결재 항목 |
|
364 |
+ sanctnMbyId: null, // 결재 주체 아이디 |
|
365 |
+ sanctnSe: this.sanctnCodes[0].code, // 결재구분 |
|
366 | 366 |
|
367 |
- clsfNm: this.formatClsf(user.clsf), |
|
368 |
- userNm: user.userNm, |
|
367 |
+ confmerNm: user.userNm, // 승인자 이름 |
|
368 |
+ clsfNm: user.clsfNm, // 직급 이름 |
|
369 | 369 |
}; |
370 | 370 |
|
371 | 371 |
this.editData.sanctnList.push(data); |
... | ... | @@ -379,12 +379,7 @@ |
379 | 379 |
}); |
380 | 380 |
}, |
381 | 381 |
|
382 |
- // 직급 매칭 |
|
383 |
- formatClsf(code) { |
|
384 |
- const clsfCode = this.cmmnCodes?.clsfCodeList?.find(item => item.code === code); |
|
385 |
- return clsfCode?.codeNm || code; |
|
386 |
- }, |
|
387 |
- |
|
382 |
+ // 이전 승인자 조회 |
|
388 | 383 |
async fnRecord() { |
389 | 384 |
try { |
390 | 385 |
const response = await findLastVcatnProc(); |
... | ... | @@ -403,6 +398,7 @@ |
403 | 398 |
} |
404 | 399 |
}, |
405 | 400 |
|
401 |
+ // 유효성 검사 |
|
406 | 402 |
validateForm() { |
407 | 403 |
if (this.$isEmpty(this.editData.vcatnKnd)) { |
408 | 404 |
alert("유형을 선택해 주세요."); |
... | ... | @@ -424,38 +420,35 @@ |
424 | 420 |
return false; |
425 | 421 |
} |
426 | 422 |
|
427 |
- if (this.dayCnt === 0.5) { |
|
428 |
- if (this.$isEmpty(this.editData.vcatnSubKnd)) { |
|
429 |
- alert("세부 유형을 선택해 주세요."); |
|
430 |
- return false; |
|
431 |
- } |
|
432 |
- } |
|
433 |
- |
|
434 | 423 |
return true; |
435 | 424 |
}, |
436 | 425 |
|
426 |
+ // 신청 |
|
437 | 427 |
async fnSave() { |
438 | 428 |
try { |
439 | 429 |
if (!this.validateForm()) { |
440 | 430 |
return; |
441 | 431 |
} |
442 | 432 |
|
433 |
+ // 데이터 세팅 |
|
434 |
+ let data = this.editData; |
|
443 | 435 |
if (!this.$isEmpty(this.pageId)) { |
444 |
- this.editData.confm_at = 'W'; |
|
436 |
+ data.confmAt = 'W'; |
|
445 | 437 |
} |
446 | 438 |
|
447 |
- const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(this.editData) : await updateVcatnProc(this.editData); |
|
439 |
+ const response = this.$isEmpty(this.pageId) ? await saveVcatnProc(data) : await updateVcatnProc(data); |
|
448 | 440 |
const message = this.$isEmpty(this.pageId) ? "등록되었습니다." : "수정되었습니다."; |
449 | 441 |
alert(message); |
450 | 442 |
|
451 | 443 |
this.fnMoveTo('view', response.data.data.pageId); |
452 | 444 |
} catch (error) { |
453 | 445 |
console.error('저장 실패:', error); |
454 |
- const message = error.response?.data?.message || "저장에 실패했습니다."; |
|
446 |
+ const message = error.response.data.message || "저장에 실패했습니다."; |
|
455 | 447 |
alert(message); |
456 | 448 |
} |
457 | 449 |
}, |
458 | 450 |
|
451 |
+ // 페이지 이동 |
|
459 | 452 |
fnMoveTo(type, id) { |
460 | 453 |
const routes = { |
461 | 454 |
'list': { name: 'hyugaStatue' }, |
--- client/views/pages/Manager/attendance/attendance.vue
+++ client/views/pages/Manager/attendance/attendance.vue
... | ... | @@ -176,7 +176,6 @@ |
176 | 176 |
created() { |
177 | 177 |
// 로컬스토리지에서 기존 데이터가 있으면 불러오기 |
178 | 178 |
const storedData = localStorage.getItem('DeptData'); |
179 |
- console.log(storedData); |
|
180 | 179 |
if (storedData) { |
181 | 180 |
this.DeptData = JSON.parse(storedData); |
182 | 181 |
} |
--- client/views/pages/Manager/attendance/hyugaStatue.vue
+++ client/views/pages/Manager/attendance/hyugaStatue.vue
... | ... | @@ -41,12 +41,12 @@ |
41 | 41 |
</tr> |
42 | 42 |
</thead> |
43 | 43 |
<tbody> |
44 |
- <template v-if="formattedListData.length > 0"> |
|
45 |
- <tr v-for="(item, idx) in formattedListData" :key="idx" @click="fnMoveTo('view', item.vcatnId)"> |
|
46 |
- <td :class="getTypeColorClass(item.formattedVcatnKnd)">{{ item.formattedVcatnKnd }}</td> |
|
47 |
- <td>{{ item.formattedBgnde }} {{ item.formattedBeginHour }}:{{ item.formattedBeginMnt }} ~ {{ item.formattedEndde }} {{ item.formattedEndHour }}:{{ item.formattedEndMnt }}</td> |
|
44 |
+ <template v-if="lists.length > 0"> |
|
45 |
+ <tr v-for="(item, idx) in lists" :key="idx" @click="fnMoveTo('view', item.vcatnId)"> |
|
46 |
+ <td>{{ item.vcatnKndNm }}</td> |
|
47 |
+ <td>{{ $formattedDates(item) }}</td> |
|
48 | 48 |
<td>{{ item.rgsde }}</td> |
49 |
- <td :class="getStatusClass(item.formattedStatus)">{{ item.formattedStatus }}</td> |
|
49 |
+ <td>{{ item.confmAtNm }}</td> |
|
50 | 50 |
</tr> |
51 | 51 |
</template> |
52 | 52 |
<tr v-else> |
... | ... | @@ -64,7 +64,7 @@ |
64 | 64 |
import { SearchOutlined } from '@ant-design/icons-vue'; |
65 | 65 |
import Pagenation from '../../../component/Pagenation.vue'; |
66 | 66 |
// API |
67 |
-import { findVcatnsSummary, findMyVcatnsProc } from '../../../../resources/api/vcatn'; |
|
67 |
+import { findVcatnsSummary, findVcatnsProc } from '../../../../resources/api/vcatn'; |
|
68 | 68 |
|
69 | 69 |
export default { |
70 | 70 |
components: { |
... | ... | @@ -82,52 +82,18 @@ |
82 | 82 |
useSummary: [], // 연차 소모성 휴가 |
83 | 83 |
notUseSummary: [], // 연차 비 소모성 휴가 |
84 | 84 |
|
85 |
- // 휴가 현황 목록 조회용 |
|
86 |
- listData: [], |
|
87 | 85 |
request: { |
88 | 86 |
vcatnKnds: null, // 휴가 종류 |
89 | 87 |
bgnde: null, // 시작일 |
90 | 88 |
endde: null, // 종료일 |
91 | 89 |
}, |
92 |
- |
|
93 |
- // 공통코드(구분, 상태) 목록 조회용 |
|
94 |
- vcatnKnds: [], |
|
95 |
- confmTypes: [], |
|
96 |
- serachRequest: { |
|
97 |
- searchType: "upperCd", |
|
98 |
- searchText: null, |
|
99 |
- }, |
|
90 |
+ lists: [], |
|
100 | 91 |
}; |
101 | 92 |
}, |
102 | 93 |
|
103 |
- computed: { |
|
104 |
- formattedListData() { |
|
105 |
- if (!this.listData || !Array.isArray(this.listData)) { |
|
106 |
- return []; |
|
107 |
- } |
|
94 |
+ computed: {}, |
|
108 | 95 |
|
109 |
- return this.listData.map(item => { |
|
110 |
- const vcatnKnd = this.vcatnKnds.find(v => v.code === item.vcatnKnd); |
|
111 |
- const confmAt = this.confmTypes.find(v => v.codeValue === item.confmAt); |
|
112 |
- return { |
|
113 |
- ...item, |
|
114 |
- formattedVcatnKnd: vcatnKnd ? vcatnKnd.codeNm : item.vcatnKnd, |
|
115 |
- formattedBgnde: item.bgnde ? item.bgnde.split(' ')[0] : '', |
|
116 |
- formattedEndde: item.endde ? item.endde.split(' ')[0] : '', |
|
117 |
- formattedBeginHour: item.beginHour ? item.beginHour.toString().padStart(2, '0') : '00', |
|
118 |
- formattedEndHour: item.endHour ? item.endHour.toString().padStart(2, '0') : '00', |
|
119 |
- formattedBeginMnt: item.beginMnt ? item.beginMnt.toString().padStart(2, '0') : '00', |
|
120 |
- formattedEndMnt: item.endMnt ? item.endMnt.toString().padStart(2, '0') : '00', |
|
121 |
- formattedStatus: confmAt ? confmAt.codeNm : item.confmAt, |
|
122 |
- }; |
|
123 |
- }); |
|
124 |
- } |
|
125 |
- }, |
|
126 |
- |
|
127 |
- created() { |
|
128 |
- this.vcatnCodes(); // 휴가 종류 코드 조회 |
|
129 |
- this.confmTypeCodes(); // 상태 코드 조회 |
|
130 |
- }, |
|
96 |
+ created() { }, |
|
131 | 97 |
|
132 | 98 |
mounted() { |
133 | 99 |
this.findSummary(); // 현황 조회 |
... | ... | @@ -135,35 +101,6 @@ |
135 | 101 |
}, |
136 | 102 |
|
137 | 103 |
methods: { |
138 |
- // 휴가 종류 코드 조회 |
|
139 |
- async confmTypeCodes() { |
|
140 |
- this.vcatnKnds = []; // 초기화 |
|
141 |
- this.serachRequest.searchText = "sanctn_mby_vcatn"; |
|
142 |
- |
|
143 |
- const codes = await this.$findCodeList(this.serachRequest); |
|
144 |
- if (codes && Array.isArray(codes)) { |
|
145 |
- for (const code of codes) { |
|
146 |
- this.serachRequest.searchText = code.code; |
|
147 |
- |
|
148 |
- const result = await this.$findCodeList(this.serachRequest); |
|
149 |
- if (result && Array.isArray(result)) { |
|
150 |
- this.vcatnKnds.push(...result); |
|
151 |
- } |
|
152 |
- } |
|
153 |
- } |
|
154 |
- }, |
|
155 |
- |
|
156 |
- // 상태 코드 조회 |
|
157 |
- async vcatnCodes() { |
|
158 |
- this.confmTypes = []; // 초기화 |
|
159 |
- this.serachRequest.searchText = "confm_code"; |
|
160 |
- |
|
161 |
- const codes = await this.$findCodeList(this.serachRequest); |
|
162 |
- if (codes && Array.isArray(codes)) { |
|
163 |
- this.confmTypes = codes; |
|
164 |
- } |
|
165 |
- }, |
|
166 |
- |
|
167 | 104 |
// 현황 조회 |
168 | 105 |
async findSummary() { |
169 | 106 |
const vm = this; |
... | ... | @@ -208,6 +145,27 @@ |
208 | 145 |
}; |
209 | 146 |
}, |
210 | 147 |
|
148 |
+ // 목록 조회 |
|
149 |
+ async findList() { |
|
150 |
+ const vm = this; |
|
151 |
+ try { |
|
152 |
+ delete vm.request.vcatnKndList; |
|
153 |
+ |
|
154 |
+ const response = await findVcatnsProc(vm.request); |
|
155 |
+ const result = response.data.data; |
|
156 |
+ |
|
157 |
+ vm.lists = result.lists; |
|
158 |
+ vm.request = result.search; |
|
159 |
+ } catch (error) { |
|
160 |
+ if (error.response) { |
|
161 |
+ alert(error.response.data.message); |
|
162 |
+ } else { |
|
163 |
+ alert("에러가 발생했습니다."); |
|
164 |
+ } |
|
165 |
+ console.error(error.message); |
|
166 |
+ }; |
|
167 |
+ }, |
|
168 |
+ |
|
211 | 169 |
// 현황에 클래스 부여 |
212 | 170 |
getBoxClass(idx) { |
213 | 171 |
if (idx === 0) return 'box'; |
... | ... | @@ -231,27 +189,6 @@ |
231 | 189 |
this.findList(); // 목록 조회 |
232 | 190 |
}, |
233 | 191 |
|
234 |
- // 목록 조회 |
|
235 |
- async findList() { |
|
236 |
- const vm = this; |
|
237 |
- try { |
|
238 |
- delete vm.request.vcatnKndList; |
|
239 |
- |
|
240 |
- const response = await findMyVcatnsProc(vm.request); |
|
241 |
- const result = response.data.data; |
|
242 |
- |
|
243 |
- vm.listData = result.lists; |
|
244 |
- vm.request = result.search; |
|
245 |
- } catch (error) { |
|
246 |
- if (error.response) { |
|
247 |
- alert(error.response.data.message); |
|
248 |
- } else { |
|
249 |
- alert("에러가 발생했습니다."); |
|
250 |
- } |
|
251 |
- console.error(error.message); |
|
252 |
- }; |
|
253 |
- }, |
|
254 |
- |
|
255 | 192 |
// 목록 필터 조회 |
256 | 193 |
fnFindUseList(item) { |
257 | 194 |
if (item.key === 'totalCo') { |
... | ... | @@ -264,27 +201,12 @@ |
264 | 201 |
|
265 | 202 |
this.findList(); // 목록 조회 |
266 | 203 |
}, |
204 |
+ |
|
205 |
+ // 목록 필터 조회 |
|
267 | 206 |
fnFindNotUseList(vcatnKnd) { |
268 | 207 |
this.request.vcatnKnds = vcatnKnd; |
269 | 208 |
|
270 | 209 |
this.findList(); // 목록 조회 |
271 |
- }, |
|
272 |
- |
|
273 |
- // 구분에 클래스 부여 |
|
274 |
- getTypeColorClass(code) { |
|
275 |
- for (let color of this.colorMap) { |
|
276 |
- if (color.code === code) { |
|
277 |
- return 'vcatnKnd ' + color.class; |
|
278 |
- } |
|
279 |
- } |
|
280 |
- return 'vcatnKnd blue'; |
|
281 |
- }, |
|
282 |
- |
|
283 |
- // 상태에 따른 클래스 반환 메소드 |
|
284 |
- getStatusClass(status) { |
|
285 |
- if (status === '승인') return 'status-approved'; |
|
286 |
- if (status === '대기') return 'status-pending'; |
|
287 |
- return ''; |
|
288 | 210 |
}, |
289 | 211 |
|
290 | 212 |
// 페이지 이동 |
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?