
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="card">
<div class="card-body">
<h2 class="card-title">부서 관리</h2>
<!-- Multi Columns Form -->
<div class="flex align-top">
<div class="sch-form-wrap search ">
<div v-for="(menu, index) in menus" :key="index" class="sidemenu">
<details class="menu-box" open>
<summary class="topmenu">
<img :src="arrow" alt="" class="arrow">
<img :src="topmenuicon" alt="">
<p>{{ menu.title }} </p>
<button @click="addSubMenu(index)" class="btn sm xsm secondary">sub +</button>
</summary>
<ul>
<li class="submenu" v-for="(submenu, subIndex) in menu.submenus" :key="subIndex">
<router-link :to="submenu.link" exact-active-class="active-link" v-slot="{ isExactActive }">
<img :src="menuicon" alt="">
<p>{{ submenu.label }}</p>
</router-link>
</li>
</ul>
</details>
</div>
<div class="buttons">
<button @click="addTopMenu"><img :src="addtopmenu" alt=""></button>
</div>
</div>
<div style="width: 100%;">
<div class=" sch-form-wrap title-wrap">
<h3><img :src="h3icon" alt="">부서 정보</h3>
<div class="buttons" style="margin: 0;">
<button type="submit" class="btn sm sm tertiary">초기화</button>
<button type="reset" class="btn sm sm secondary">등록</button>
<button type="delete" class="btn sm sm btn-red">삭제</button>
</div>
</div>
<form class="row g-3 pt-3 needs-validation detail" @submit.prevent="handleSubmit"
style="margin-bottom: 3rem;">
<div class="col-12">
<label for="purpose" class="form-label">상위부서</label>
<input type="text" class="form-control" id="purpose" v-model="purpose" readonly />
</div>
<div class="col-12">
<label for="purpose" class="form-label">
<p>부서명
<p class="require"><img :src="require" alt=""></p>
</p>
</label>
<input type="text" class="form-control" id="purpose" v-model="purpose" />
</div>
<div class="col-12 chuljang border-x">
<label for="prvonsh" class="form-label">부서설명</label>
<input type="text" class="form-control textarea" id="reason" v-model="reason" />
</div>
</form>
<div class=" sch-form-wrap title-wrap">
<h3><img :src="h3icon" alt="">부서 사용자</h3>
<div class="buttons" style="margin: 0;">
<button type="reset" class="btn sm sm secondary" @click="showPopup = true">사용자 추가</button>
<button type="delete" class="btn sm sm btn-red" @click="removeMember(index)">사용자 삭제</button>
</div>
<HrPopup v-if="showPopup" @close="showPopup = false" @select="addMember"/>
</div>
<div class="tbl-wrap chk-area">
<table id="myTable" class="tbl data">
<thead>
<tr>
<th>선택</th>
<th>직급</th>
<th>이름</th>
<th>부서장</th>
</tr>
</thead>
<!-- 동적으로 <td> 생성 -->
<tbody>
<tr v-for="(member, index) in members" :key="index">
<td>
<div class="form-check">
<input type="checkbox" :id="`chk_${index}`" :value="member.name" v-model="member.checked" />
<label :for="`chk_${index}`"></label>
</div>
</td>
<td>{{ member.position }}</td>
<td>{{ member.name }}</td>
<td>
<div class="form-check">
<input type="radio" name="manager" :id="`rdo_${index}`" :value="member.name"
v-model="selectedManager" />
<label :for="`rdo_${index}`"></label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<ul>
<!-- 왼쪽 화살표 (이전 페이지) -->
<li class="arrow" :class="{ disabled: currentPage === 1 }" @click="changePage(currentPage - 1)">
<
</li>
<!-- 페이지 번호 -->
<li v-for="page in totalPages" :key="page" :class="{ active: currentPage === page }"
@click="changePage(page)">
{{ page }}
</li>
<!-- 오른쪽 화살표 (다음 페이지) -->
<li class="arrow" :class="{ disabled: currentPage === totalPages }" @click="changePage(currentPage + 1)">
>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
import { PlusCircleFilled, CloseOutlined, DownOutlined } from '@ant-design/icons-vue';
import HrPopup from '../../../component/Popup/HrPopup.vue';
const isOpen = ref(false)
export default {
data() {
const today = new Date().toISOString().split('T')[0];
return {
selectedManager: '',
showPopup: false,
menus: [
{
title: '부서1',
submenus: [
{
label: '직원검색',
link: { name: 'hrSearch' },
},
],
},
],
currentPage: 1,
totalPages: 3,
members: [] ,
selectedManager: null,
h3icon: "/client/resources/img/h3icon.png",
require: "/client/resources/img/require.png",
menuicon: "/client/resources/img/arrow-rg.png",
topmenuicon: "/client/resources/img/topmenu.png",
arrow: "/client/resources/img/arrow.png",
addtopmenu: "/client/resources/img/addtopmenu.png",
addsubmenu: "/client/resources/img/addsubmenu.png",
fileName: '',
startDate: today,
startTime: '09:00',
endDate: today,
endTime: '18:00',
where: '',
purpose: '',
approvals: [
{
category: '결재',
name: '',
},
],
receipts: [
{
type: '개인결제',
category: '결재',
category1: '구분',
},
],
};
},
components: {
PlusCircleFilled, CloseOutlined, DownOutlined, HrPopup
},
computed: {
loginUser() {
const authStore = useAuthStore();
return authStore.getLoginUser;
},
},
methods: {
addMember(selectedUser) {
this.members.push({
position: selectedUser.position,
name: selectedUser.name, // or other fields if needed
});
this.showPopup = false; // 팝업 닫기
},
removeMember() {
this.members = this.members.filter(member => !member.checked);
},
addTopMenu() {
const newIndex = this.menus.length + 1;
this.menus.push({
title: `부서${newIndex}`,
submenus: [],
});
},
addSubMenu(menuIndex) {
this.menus[menuIndex].submenus.push({
label: `신규메뉴${this.menus[menuIndex].submenus.length + 1}`,
link: { name: 'hrSearch' },
});
},
goToPage(type) {
if (type === '회의록 등록') {
this.$router.push({ name: 'meetingInsert' });
} else if (type === '출장') {
this.$router.push({ name: 'ChuljangDetail' });
}
},
handleFileUpload(event) {
const file = event.target.files[0];
if (file) {
this.fileName = file.name;
}
},
addApproval() {
this.approvals.push({
category: '결재',
name: '',
});
},
addReceipt() {
this.receipts.push({
type: '개인결제',
category: '결재',
category1: '',
name: '',
file: null,
});
},
// 승인자 삭제
removeApproval(index) {
this.approvals.splice(index, 1);
},
removeReceipt(index) {
this.receipts.splice(index, 1);
},
validateForm() {
// 필수 입력 필드 체크
if (
this.startDate &&
this.startTime &&
this.endDate &&
this.endTime &&
this.where &&
this.purpose.trim() !== ""
) {
this.isFormValid = true;
} else {
this.isFormValid = false;
}
},
calculateDayCount() {
const start = new Date(`${this.startDate}T${this.startTime}:00`);
const end = new Date(`${this.endDate}T${this.endTime}:00`);
let totalHours = (end - start) / (1000 * 60 * 60); // 밀리초를 시간 단위로 변환
if (this.startDate !== this.endDate) {
// 시작일과 종료일이 다른경우
const startDateObj = new Date(this.startDate);
const endDateObj = new Date(this.endDate);
const daysDifference = (endDateObj - startDateObj) / (1000 * 60 * 60 * 24); // 두 날짜 사이의 차이를 일수로 계산
if (this.startTime !== "09:00" || this.endTime !== "18:00") {
this.dayCount = daysDifference + 0.5; // 시간 조건이 기준에서 벗어날 경우
} else {
this.dayCount = Math.ceil(daysDifference + 1); // 시간 조건이 기준에 맞을 경우
}
} else {
// 시작일과 종료일이 같은 경우
if (this.startTime !== "09:00" || this.endTime !== "18:00") {
this.dayCount = 0.5; // 시작 시간 또는 종료 시간이 기준과 다를 경우 0.5
} else {
this.dayCount = 1; // 기준 시간(09:00~18:00)이 맞으면 1일로 간주
}
}
this.validateForm(); // dayCount 변경 후 폼 재검증
},
handleSubmit() {
this.validateForm(); // 제출 시 유효성 확인
if (this.isFormValid) {
localStorage.setItem('ChuljangFormData', JSON.stringify(this.$data));
alert("승인 요청이 완료되었습니다.");
// 추가 처리 로직 (API 요청 등)
} else {
alert("모든 필드를 올바르게 작성해주세요.");
}
},
loadFormData() {
const savedData = localStorage.getItem('ChuljangFormData');
if (savedData) {
this.$data = JSON.parse(savedData);
}
},
},
mounted() {
// Load the saved form data when the page is loaded
this.loadFormData();
},
watch: {
startDate: 'calculateDayCount',
startTime: 'calculateDayCount',
endDate: 'calculateDayCount',
endTime: 'calculateDayCount',
where: 'validateForm',
purpose: "validateForm",
},
};
</script>
<style scoped>
/* 필요한 스타일 추가 */
</style>