수정, 등록 나누고 삭제 추가
This commit is contained in:
parent
0c1e7bc5dd
commit
581709430f
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mb-2 row" >
|
<div class="mb-2 row">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<label :for="name" class="col-md-2 col-form-label">
|
<label :for="name" class="col-md-2 col-form-label">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
@ -28,7 +28,6 @@
|
|||||||
placeholder="기본주소"
|
placeholder="기본주소"
|
||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -87,7 +86,11 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({
|
||||||
|
postcode: '',
|
||||||
|
address: '',
|
||||||
|
detailAddress: ''
|
||||||
|
}),
|
||||||
required: false
|
required: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -95,13 +98,13 @@ const props = defineProps({
|
|||||||
// watch 설정 수정
|
// watch 설정 수정
|
||||||
watch(() => props.modelValue, (newValue) => {
|
watch(() => props.modelValue, (newValue) => {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
postcode.value = newValue.PROJCTZIP || '';
|
postcode.value = newValue.postcode || '';
|
||||||
address.value = newValue.PROJCTARR || '';
|
address.value = newValue.address || '';
|
||||||
detailAddress.value = newValue.PROJCTDTL || '';
|
detailAddress.value = newValue.detailAddress || '';
|
||||||
}
|
}
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
const emits = defineEmits(['update:data', 'update:alert']);
|
const emits = defineEmits(['update:data', 'update:alert', 'update:modelValue']);
|
||||||
|
|
||||||
// 주소 검색 팝업 열기
|
// 주소 검색 팝업 열기
|
||||||
const openAddressSearch = () => {
|
const openAddressSearch = () => {
|
||||||
@ -136,6 +139,7 @@ const emitAddressData = () => {
|
|||||||
detailAddress: detailAddress.value,
|
detailAddress: detailAddress.value,
|
||||||
};
|
};
|
||||||
emits('update:data', fullAddress);
|
emits('update:data', fullAddress);
|
||||||
|
emits('update:modelValue', fullAddress); // modelValue도 부모로 전달
|
||||||
};
|
};
|
||||||
|
|
||||||
// isAlert를 false로 설정
|
// isAlert를 false로 설정
|
||||||
|
|||||||
@ -16,11 +16,11 @@
|
|||||||
:min="min"
|
:min="min"
|
||||||
@focusout="$emit('focusout', modelValue)"
|
@focusout="$emit('focusout', modelValue)"
|
||||||
/>
|
/>
|
||||||
<div class="invalid-feedback" :class="isAlert ? 'display-block' : ''">
|
<div class="invalid-feedback" :class="isAlert ? 'd-block' : ''">
|
||||||
{{ title }}을 확인해주세요.
|
{{ title }}을 확인해주세요.
|
||||||
</div>
|
</div>
|
||||||
<!-- 카테고리 중복 -->
|
<!-- 카테고리 중복 -->
|
||||||
<div class="invalid-feedback" :class="isCateAlert ? 'display-block' : ''">
|
<div class="invalid-feedback" :class="isCateAlert ? 'd-block' : ''">
|
||||||
카테고리 중복입니다.
|
카테고리 중복입니다.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,8 +3,13 @@
|
|||||||
<div class="row g-0">
|
<div class="row g-0">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<!-- 제목 -->
|
<!-- 제목 -->
|
||||||
<h5 class="card-title">
|
<h5 class="card-title d-flex justify-content-between">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<EditBtn @click.stop="openEditModal" />
|
||||||
|
<DeleteBtn @click.stop="handleDelete" class="ms-1"/>
|
||||||
|
</div>
|
||||||
</h5>
|
</h5>
|
||||||
<!-- 날짜 -->
|
<!-- 날짜 -->
|
||||||
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
|
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
|
||||||
@ -27,20 +32,14 @@
|
|||||||
<!-- 주소 -->
|
<!-- 주소 -->
|
||||||
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
|
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
|
||||||
<div class="d-flex" @click.stop="isPopoverVisible = !isPopoverVisible">
|
<div class="d-flex" @click.stop="isPopoverVisible = !isPopoverVisible">
|
||||||
<i
|
<i class="bx bxs-map cursor-pointer" ref="mapIconRef"></i>
|
||||||
class="bx bxs-map cursor-pointer"
|
|
||||||
ref="mapIconRef"
|
|
||||||
></i>
|
|
||||||
<div class="ms-2">주소</div>
|
<div class="ms-2">주소</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-12 position-relative">
|
<div class="ms-12 position-relative">
|
||||||
{{ address }} {{ addressdtail }}
|
{{ address }} {{ addressdtail }}
|
||||||
<!-- 팝오버 -->
|
<!-- 팝오버 -->
|
||||||
<div
|
<div v-if="isPopoverVisible" class="position-absolute w-100 map text-end">
|
||||||
v-if="isPopoverVisible"
|
<button type="button" class="btn-close popover-close" @click.stop="isPopoverVisible = !isPopoverVisible"></button>
|
||||||
class="position-absolute w-100 map text-end"
|
|
||||||
>
|
|
||||||
<button type="button" class="btn-close popover-close" @click.stop="isPopoverVisible = !isPopoverVisible"></button>
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body p-1">
|
<div class="card-body p-1">
|
||||||
<KakaoMap
|
<KakaoMap
|
||||||
@ -49,7 +48,7 @@
|
|||||||
:lng="coordinates.lng"
|
:lng="coordinates.lng"
|
||||||
:draggable="false"
|
:draggable="false"
|
||||||
class="w-100 h-px-200"
|
class="w-100 h-px-200"
|
||||||
>
|
>
|
||||||
<KakaoMapMarker
|
<KakaoMapMarker
|
||||||
:lat="coordinates.lat"
|
:lat="coordinates.lat"
|
||||||
:lng="coordinates.lng"
|
:lng="coordinates.lng"
|
||||||
@ -59,39 +58,122 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn ms-auto text-white" :style="`background-color: ${projctCol} !important;`" @click.stop="openModal">log</button>
|
<button type="button" class="btn ms-auto text-white" :style="`background-color: ${projctColor} !important;`" @click.stop="openModal">log</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 로그 모달 -->
|
||||||
<CenterModal :display="isModalOpen" @close="closeModal">
|
<CenterModal :display="isModalOpen" @close="closeModal">
|
||||||
<template #title> Log </template>
|
<template #title> Log </template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="ms-4 mt-2 border p-3" v-if="logData">
|
<div v-if="logData.length > 0">
|
||||||
<p class="mb-1">{{ logData.createDate }}</p>
|
<div
|
||||||
<strong>[{{ logData.creator }}] 프로젝트 등록</strong>
|
v-for="(log, index) in logData"
|
||||||
</div>
|
:key="index"
|
||||||
|
class="ms-4 mt-2 border p-3"
|
||||||
<div class="log-item" v-if="logData?.updateDate">
|
>
|
||||||
<div class="ms-4 mt-2 border p-3">
|
<p class="mb-1">{{ log.logDate }}</p>
|
||||||
<p class="mb-1">{{ logData.updateDate }}</p>
|
<strong>{{ log.logMessage }}</strong>
|
||||||
<strong>[{{ logData.updater }}] 프로젝트 수정</strong>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<BackButton @click="closeModal" />
|
<BackBtn @click="closeModal" />
|
||||||
|
</template>
|
||||||
|
</CenterModal>
|
||||||
|
|
||||||
|
<!-- 수정 모달 -->
|
||||||
|
<CenterModal :display="isEditModalOpen" @close="closeEditModal">
|
||||||
|
<template #title> 프로젝트 수정 </template>
|
||||||
|
<template #body>
|
||||||
|
<FormInput
|
||||||
|
title="이름"
|
||||||
|
name="name"
|
||||||
|
:is-essential="true"
|
||||||
|
:is-alert="nameAlert"
|
||||||
|
:modelValue="selectedProject.PROJCTNAM"
|
||||||
|
@update:modelValue="selectedProject.PROJCTNAM = $event"
|
||||||
|
@update:alert="nameAlert = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormSelect
|
||||||
|
title="컬러"
|
||||||
|
name="color"
|
||||||
|
:is-essential="true"
|
||||||
|
:is-label="true"
|
||||||
|
:is-common="true"
|
||||||
|
:data="allColors"
|
||||||
|
:value="selectedProject.PROJCTCOL"
|
||||||
|
@update:data="selectedProject.PROJCTCOL = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormInput
|
||||||
|
title="시작일"
|
||||||
|
type="date"
|
||||||
|
name="startDay"
|
||||||
|
:is-essential="true"
|
||||||
|
:modelValue="selectedProject.PROJCTSTR"
|
||||||
|
@update:modelValue="selectedProject.PROJCTSTR = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormInput
|
||||||
|
title="종료일"
|
||||||
|
type="date"
|
||||||
|
name="endDay"
|
||||||
|
:modelValue="selectedProject.PROJCTEND"
|
||||||
|
@update:modelValue="selectedProject.PROJCTEND = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormInput
|
||||||
|
title="설명"
|
||||||
|
name="description"
|
||||||
|
:modelValue="selectedProject.PROJCTDES"
|
||||||
|
@update:modelValue="selectedProject.PROJCTDES = $event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ArrInput
|
||||||
|
title="주소"
|
||||||
|
name="address"
|
||||||
|
:is-essential="true"
|
||||||
|
:is-row="true"
|
||||||
|
:modelValue="{
|
||||||
|
address: selectedProject.PROJCTARR,
|
||||||
|
detailAddress: selectedProject.PROJCTDTL,
|
||||||
|
postcode: selectedProject.PROJCTZIP
|
||||||
|
}"
|
||||||
|
@update:data="updateAddress"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<BackButton @click="closeEditModal" />
|
||||||
|
<SaveButton @click="handleUpdate" />
|
||||||
</template>
|
</template>
|
||||||
</CenterModal>
|
</CenterModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineProps, onMounted, ref } from 'vue';
|
import { defineProps, onMounted, ref, computed, inject } from 'vue';
|
||||||
import UserList from '@c/user/UserList.vue';
|
import UserList from '@c/user/UserList.vue';
|
||||||
import CenterModal from '@c/modal/CenterModal.vue';
|
import CenterModal from '@c/modal/CenterModal.vue';
|
||||||
import $api from '@api';
|
import $api from '@api';
|
||||||
import { KakaoMap, KakaoMapMarker } from 'vue3-kakao-maps';
|
import { KakaoMap, KakaoMapMarker } from 'vue3-kakao-maps';
|
||||||
|
import BackBtn from '@c/button/BackBtn.vue';
|
||||||
|
import BackButton from '@c/button/BackBtn.vue';
|
||||||
|
import SaveButton from '@c/button/SaveBtn.vue';
|
||||||
|
import EditBtn from '../button/EditBtn.vue';
|
||||||
|
import DeleteBtn from '../button/DeleteBtn.vue';
|
||||||
|
import FormInput from '@c/input/FormInput.vue';
|
||||||
|
import FormSelect from '@c/input/FormSelect.vue';
|
||||||
|
import ArrInput from '@c/input/ArrInput.vue';
|
||||||
|
import { useToastStore } from '@s/toastStore';
|
||||||
|
import { useUserInfoStore } from '@/stores/useUserInfoStore';
|
||||||
|
import commonApi from '@/common/commonApi';
|
||||||
|
|
||||||
|
// 스토어
|
||||||
|
const toastStore = useToastStore();
|
||||||
|
const userStore = useUserInfoStore();
|
||||||
|
|
||||||
// Props 정의
|
// Props 정의
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -120,39 +202,144 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
addressZip: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
projctSeq: {
|
projctSeq: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
projctCol: {
|
projctCol: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
projctColor: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
defineEmits(['click']);
|
// Emit 정의
|
||||||
|
const emit = defineEmits(['update']);
|
||||||
|
|
||||||
|
// 로그 모달 상태
|
||||||
const isModalOpen = ref(false);
|
const isModalOpen = ref(false);
|
||||||
const logData = ref(null);
|
const logData = ref([]);
|
||||||
|
|
||||||
|
// 주소 팝오버 상태
|
||||||
const isPopoverVisible = ref(false);
|
const isPopoverVisible = ref(false);
|
||||||
const mapIconRef = ref(null);
|
const mapIconRef = ref(null);
|
||||||
const coordinates = ref(null);
|
const coordinates = ref(null);
|
||||||
|
|
||||||
const fetchLogData = async () => {
|
// 수정 모달 상태
|
||||||
const response = await $api.get(`project/log/${props.projctSeq}`);
|
const isEditModalOpen = ref(false);
|
||||||
logData.value = response.data.data.length > 0 ? response.data.data[0] : {};
|
const originalColor = ref('');
|
||||||
|
const nameAlert = ref(false);
|
||||||
|
const user = ref(null);
|
||||||
|
|
||||||
|
// 수정할 프로젝트 데이터
|
||||||
|
const selectedProject = ref({
|
||||||
|
PROJCTSEQ: props.projctSeq,
|
||||||
|
PROJCTNAM: props.title,
|
||||||
|
PROJCTSTR: props.strdate,
|
||||||
|
PROJCTEND: props.enddate,
|
||||||
|
PROJCTZIP: props.addressZip,
|
||||||
|
PROJCTARR: props.address,
|
||||||
|
PROJCTDTL: props.addressdtail,
|
||||||
|
PROJCTDES: props.description,
|
||||||
|
PROJCTCOL: props.projctCol,
|
||||||
|
projctcolor: props.projctColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 컬러 목록 가져오기
|
||||||
|
const { colorList } = commonApi({
|
||||||
|
loadColor: true,
|
||||||
|
colorType: 'YNP',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 기존 컬러 + 사용 가능 한 컬러
|
||||||
|
const allColors = computed(() => {
|
||||||
|
const existingColor = { value: selectedProject.value.PROJCTCOL, label: selectedProject.value.projctcolor };
|
||||||
|
return [existingColor, ...colorList.value];
|
||||||
|
});
|
||||||
|
|
||||||
|
// 수정 :: 주소
|
||||||
|
const updateAddress = addressData => {
|
||||||
|
selectedProject.value = {
|
||||||
|
...selectedProject.value,
|
||||||
|
PROJCTZIP: addressData.postcode,
|
||||||
|
PROJCTARR: addressData.address,
|
||||||
|
PROJCTDTL: addressData.detailAddress,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 로그 데이터 가져오기
|
||||||
|
const getLogData = async () => {
|
||||||
|
const res = await $api.get(`project/log/${props.projctSeq}`);
|
||||||
|
|
||||||
|
logData.value = res.data.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 로그 모달 열기
|
||||||
const openModal = async () => {
|
const openModal = async () => {
|
||||||
await fetchLogData();
|
await getLogData();
|
||||||
isModalOpen.value = true;
|
isModalOpen.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 로그 모달 닫기
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
isModalOpen.value = false;
|
isModalOpen.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 수정 모달 열기
|
||||||
|
const openEditModal = () => {
|
||||||
|
isEditModalOpen.value = true;
|
||||||
|
originalColor.value = props.projctCol;
|
||||||
|
|
||||||
|
// 사용자 정보 가져오기 (필요한 경우)
|
||||||
|
if (!user.value) {
|
||||||
|
userStore.userInfo().then(() => {
|
||||||
|
user.value = userStore.user;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 수정 모달 닫기
|
||||||
|
const closeEditModal = () => {
|
||||||
|
isEditModalOpen.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 프로젝트 수정
|
||||||
|
const handleUpdate = () => {
|
||||||
|
nameAlert.value = selectedProject.value.PROJCTNAM.trim() === '';
|
||||||
|
|
||||||
|
if (nameAlert.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$api.patch('project/update', {
|
||||||
|
projctSeq: selectedProject.value.PROJCTSEQ,
|
||||||
|
projctNam: selectedProject.value.PROJCTNAM,
|
||||||
|
projctCol: selectedProject.value.PROJCTCOL,
|
||||||
|
projctArr: selectedProject.value.PROJCTARR,
|
||||||
|
projctDtl: selectedProject.value.PROJCTDTL,
|
||||||
|
projctZip: selectedProject.value.PROJCTZIP,
|
||||||
|
projctStr: selectedProject.value.PROJCTSTR,
|
||||||
|
projctEnd: selectedProject.value.PROJCTEND || null,
|
||||||
|
projctDes: selectedProject.value.PROJCTDES || null,
|
||||||
|
projctUmb: user.value?.name,
|
||||||
|
originalColor: originalColor.value === selectedProject.value.PROJCTCOL ? null : originalColor.value,
|
||||||
|
}).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
toastStore.onToast('수정이 완료 되었습니다.', 's');
|
||||||
|
closeEditModal();
|
||||||
|
// 상위 컴포넌트에 업데이트 알림
|
||||||
|
emit('update');
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 주소를 좌표로 변환하는 함수
|
// 주소를 좌표로 변환하는 함수
|
||||||
const convertAddressToCoordinates = () => {
|
const convertAddressToCoordinates = () => {
|
||||||
@ -174,11 +361,27 @@ const convertAddressToCoordinates = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 컴포넌트 마운트 시 주소 변환
|
// 프로젝트 삭제
|
||||||
onMounted(() => {
|
const handleDelete = () => {
|
||||||
|
$api.patch('project/delete', {
|
||||||
|
projctSeq: props.projctSeq,
|
||||||
|
projctCol: props.projctCol,
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
toastStore.onToast('삭제가 완료되었습니다.', 's');
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 컴포넌트 마운트 시 실행
|
||||||
|
onMounted(async () => {
|
||||||
convertAddressToCoordinates();
|
convertAddressToCoordinates();
|
||||||
|
|
||||||
|
// 사용자 정보 가져오기
|
||||||
|
await userStore.userInfo();
|
||||||
|
user.value = userStore.user;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<p class="text-muted mt-4">등록된 프로젝트가 없습니다.</p>
|
<p class="text-muted mt-4">등록된 프로젝트가 없습니다.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="post in projectStore.projectList" :key="post.PROJCTSEQ" @click="openEditModal(post)" class="cursor-pointer">
|
<div v-for="post in projectStore.projectList" :key="post.PROJCTSEQ">
|
||||||
<ProjectCard
|
<ProjectCard
|
||||||
:title="post.PROJCTNAM"
|
:title="post.PROJCTNAM"
|
||||||
:description="post.PROJCTDES"
|
:description="post.PROJCTDES"
|
||||||
@ -19,8 +19,11 @@
|
|||||||
:enddate="post.PROJCTEND"
|
:enddate="post.PROJCTEND"
|
||||||
:address="post.PROJCTARR"
|
:address="post.PROJCTARR"
|
||||||
:addressdtail="post.PROJCTDTL"
|
:addressdtail="post.PROJCTDTL"
|
||||||
|
:addressZip="post.PROJCTZIP"
|
||||||
:projctSeq="post.PROJCTSEQ"
|
:projctSeq="post.PROJCTSEQ"
|
||||||
:projctCol="post.projctcolor"
|
:projctCol="post.PROJCTCOL"
|
||||||
|
:projctColor="post.projctcolor"
|
||||||
|
@update="getProjectList"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -36,8 +39,8 @@
|
|||||||
:is-essential="true"
|
:is-essential="true"
|
||||||
:is-alert="nameAlert"
|
:is-alert="nameAlert"
|
||||||
:modelValue="name"
|
:modelValue="name"
|
||||||
@update:modelValue="name = $event"
|
|
||||||
@update:alert="nameAlert = $event"
|
@update:alert="nameAlert = $event"
|
||||||
|
@update:modelValue="name = $event"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormSelect
|
<FormSelect
|
||||||
@ -80,6 +83,7 @@
|
|||||||
:isEssential="true"
|
:isEssential="true"
|
||||||
:is-row="true"
|
:is-row="true"
|
||||||
:is-alert="addressAlert"
|
:is-alert="addressAlert"
|
||||||
|
:modelValue="addressData"
|
||||||
@update:data="handleAddressUpdate"
|
@update:data="handleAddressUpdate"
|
||||||
@update:alert="addressAlert = $event"
|
@update:alert="addressAlert = $event"
|
||||||
/>
|
/>
|
||||||
@ -90,70 +94,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</CenterModal>
|
</CenterModal>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- 수정 모달 -->
|
|
||||||
<CenterModal :display="isEditModalOpen" @close="closeEditModal">
|
|
||||||
<template #title> 프로젝트 수정 </template>
|
|
||||||
<template #body>
|
|
||||||
<FormInput
|
|
||||||
title="이름"
|
|
||||||
name="name"
|
|
||||||
:is-essential="true"
|
|
||||||
:is-alert="nameAlert"
|
|
||||||
:modelValue="selectedProject.PROJCTNAM"
|
|
||||||
@update:modelValue="selectedProject.PROJCTNAM = $event"
|
|
||||||
@update:alert="nameAlert = $event"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormSelect
|
|
||||||
title="컬러"
|
|
||||||
name="color"
|
|
||||||
:is-essential="true"
|
|
||||||
:is-label="true"
|
|
||||||
:is-common="true"
|
|
||||||
:data="allColors"
|
|
||||||
:value="selectedProject.PROJCTCOL"
|
|
||||||
@update:data="selectedProject.PROJCTCOL = $event"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInput
|
|
||||||
title="시작일"
|
|
||||||
type="date"
|
|
||||||
name="startDay"
|
|
||||||
:is-essential="true"
|
|
||||||
:modelValue="selectedProject.PROJCTSTR"
|
|
||||||
@update:modelValue="selectedProject.PROJCTSTR = $event"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInput
|
|
||||||
title="종료일"
|
|
||||||
type="date"
|
|
||||||
name="endDay"
|
|
||||||
:modelValue="selectedProject.PROJCTEND"
|
|
||||||
@update:modelValue="selectedProject.PROJCTEND = $event"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormInput
|
|
||||||
title="설명"
|
|
||||||
name="description"
|
|
||||||
:modelValue="selectedProject.PROJCTDES"
|
|
||||||
@update:modelValue="selectedProject.PROJCTDES = $event"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ArrInput
|
|
||||||
title="주소"
|
|
||||||
name="address"
|
|
||||||
:is-essential="true"
|
|
||||||
:is-row="true"
|
|
||||||
:modelValue="selectedProject"
|
|
||||||
@update:data="updateAddress"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<BackButton @click="closeEditModal" />
|
|
||||||
<SaveButton @click="handleUpdate" />
|
|
||||||
</template>
|
|
||||||
</CenterModal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -193,29 +133,17 @@
|
|||||||
const isCreateModalOpen = ref(false);
|
const isCreateModalOpen = ref(false);
|
||||||
const name = ref('');
|
const name = ref('');
|
||||||
const color = ref('');
|
const color = ref('');
|
||||||
const address = ref('');
|
|
||||||
const detailAddress = ref('');
|
|
||||||
const postcode = ref('');
|
|
||||||
const startDay = ref(today);
|
const startDay = ref(today);
|
||||||
const endDay = ref('');
|
const endDay = ref('');
|
||||||
const description = ref('');
|
const description = ref('');
|
||||||
const nameAlert = ref(false);
|
const nameAlert = ref(false);
|
||||||
const addressAlert = ref(false);
|
const addressAlert = ref(false);
|
||||||
|
|
||||||
// 수정 모달 상태
|
const addressData = ref({
|
||||||
const isEditModalOpen = ref(false);
|
postcode: '',
|
||||||
const originalColor = ref('');
|
address: '',
|
||||||
const selectedProject = ref({
|
detailAddress: ''
|
||||||
PROJCTSEQ: '',
|
|
||||||
PROJCTNAM: '',
|
|
||||||
PROJCTSTR: '',
|
|
||||||
PROJCTEND: '',
|
|
||||||
PROJCTZIP: '',
|
|
||||||
PROJCTARR: '',
|
|
||||||
PROJCTDTL: '',
|
|
||||||
PROJCTDES: '',
|
|
||||||
PROJCTCOL: '',
|
|
||||||
projctcolor: '',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// API 호출
|
// API 호출
|
||||||
@ -261,9 +189,11 @@
|
|||||||
const formReset = () => {
|
const formReset = () => {
|
||||||
name.value = '';
|
name.value = '';
|
||||||
color.value = '';
|
color.value = '';
|
||||||
address.value = '';
|
addressData.value = {
|
||||||
detailAddress.value = '';
|
postcode: '',
|
||||||
postcode.value = '';
|
address: '',
|
||||||
|
detailAddress: ''
|
||||||
|
};
|
||||||
startDay.value = today;
|
startDay.value = today;
|
||||||
endDay.value = '';
|
endDay.value = '';
|
||||||
description.value = '';
|
description.value = '';
|
||||||
@ -272,30 +202,43 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 등록 :: 주소 업데이트 핸들러
|
// 등록 :: 주소 업데이트 핸들러
|
||||||
const handleAddressUpdate = addressData => {
|
const handleAddressUpdate = (data) => {
|
||||||
address.value = addressData.address;
|
addressData.value = data;
|
||||||
detailAddress.value = addressData.detailAddress;
|
};
|
||||||
postcode.value = addressData.postcode;
|
|
||||||
};
|
// 시작일이나 종료일이 변경될 때마다 종료일을 유효성 검사
|
||||||
|
watch([startDay, endDay], () => {
|
||||||
|
if (startDay.value && endDay.value) {
|
||||||
|
const start = new Date(startDay.value);
|
||||||
|
const end = new Date(endDay.value);
|
||||||
|
|
||||||
|
// 종료일이 시작일보다 이전 날짜라면 종료일을 시작일로 맞추기
|
||||||
|
if (end < start) {
|
||||||
|
endDay.value = startDay.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 프로젝트 등록
|
// 프로젝트 등록
|
||||||
const handleCreate = async () => {
|
const handleCreate = async () => {
|
||||||
|
|
||||||
nameAlert.value = name.value.trim() === '';
|
nameAlert.value = name.value.trim() === '';
|
||||||
addressAlert.value = address.value.trim() === '';
|
addressAlert.value = addressData.value.address.trim() === '';
|
||||||
|
|
||||||
if (nameAlert.value || addressAlert.value) {
|
if (nameAlert.value || addressAlert.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$api.post('project/insert', {
|
$api.post('project/insert', {
|
||||||
|
|
||||||
projctNam: name.value,
|
projctNam: name.value,
|
||||||
projctCol: color.value,
|
projctCol: color.value,
|
||||||
projctStr: startDay.value,
|
projctStr: startDay.value,
|
||||||
projctEnd: endDay.value || null,
|
projctEnd: endDay.value || null,
|
||||||
projctDes: description.value || null,
|
projctDes: description.value || null,
|
||||||
projctArr: address.value,
|
projctArr: addressData.value.address,
|
||||||
projctDtl: detailAddress.value,
|
projctDtl: addressData.value.detailAddress,
|
||||||
projctZip: postcode.value,
|
projctZip: addressData.value.postcode,
|
||||||
projctCmb: user.value.name,
|
projctCmb: user.value.name,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
@ -306,84 +249,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 수정 모달 관리
|
|
||||||
const openEditModal = post => {
|
|
||||||
isEditModalOpen.value = true;
|
|
||||||
selectedProject.value = { ...post };
|
|
||||||
originalColor.value = post.PROJCTCOL;
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeEditModal = () => {
|
|
||||||
isEditModalOpen.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 기존 컬러 + 사용 가능 한 컬러
|
|
||||||
const allColors = computed(() => {
|
|
||||||
const existingColor = { value: selectedProject.value.PROJCTCOL, label: selectedProject.value.projctcolor };
|
|
||||||
return [existingColor, ...colorList.value];
|
|
||||||
});
|
|
||||||
|
|
||||||
// 변경된 내용 있는지 확인
|
|
||||||
const hasChanges = computed(() => {
|
|
||||||
const original = projectStore.projectList.find(p => p.PROJCTSEQ === selectedProject.value.PROJCTSEQ);
|
|
||||||
if (!original) return false;
|
|
||||||
|
|
||||||
return (
|
|
||||||
original.PROJCTNAM !== selectedProject.value.PROJCTNAM ||
|
|
||||||
original.PROJCTCOL !== selectedProject.value.PROJCTCOL ||
|
|
||||||
original.PROJCTARR !== selectedProject.value.PROJCTARR ||
|
|
||||||
original.PROJCTDTL !== selectedProject.value.PROJCTDTL ||
|
|
||||||
original.PROJCTZIP !== selectedProject.value.PROJCTZIP ||
|
|
||||||
original.PROJCTSTR !== selectedProject.value.PROJCTSTR ||
|
|
||||||
original.PROJCTEND !== selectedProject.value.PROJCTEND ||
|
|
||||||
original.PROJCTDES !== selectedProject.value.PROJCTDES
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 수정 :: 주소
|
|
||||||
const updateAddress = addressData => {
|
|
||||||
selectedProject.value = {
|
|
||||||
...selectedProject.value,
|
|
||||||
PROJCTZIP: addressData.postcode,
|
|
||||||
PROJCTARR: addressData.address,
|
|
||||||
PROJCTDTL: addressData.detailAddress,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 프로젝트 수정
|
|
||||||
const handleUpdate = () => {
|
|
||||||
nameAlert.value = selectedProject.value.PROJCTNAM.trim() === '';
|
|
||||||
|
|
||||||
if (nameAlert.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasChanges.value) {
|
|
||||||
toastStore.onToast('변경된 내용이 없습니다.', 'e');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$api.patch('project/update', {
|
|
||||||
projctSeq: selectedProject.value.PROJCTSEQ,
|
|
||||||
projctNam: selectedProject.value.PROJCTNAM,
|
|
||||||
projctCol: selectedProject.value.PROJCTCOL,
|
|
||||||
projctArr: selectedProject.value.PROJCTARR,
|
|
||||||
projctDtl: selectedProject.value.PROJCTDTL,
|
|
||||||
projctZip: selectedProject.value.PROJCTZIP,
|
|
||||||
projctStr: selectedProject.value.PROJCTSTR,
|
|
||||||
projctEnd: selectedProject.value.PROJCTEND || null,
|
|
||||||
projctDes: selectedProject.value.PROJCTDES || null,
|
|
||||||
projctUmb: user.value.name,
|
|
||||||
originalColor: originalColor.value === selectedProject.value.PROJCTCOL ? null : originalColor.value,
|
|
||||||
}).then(res => {
|
|
||||||
if (res.status === 200) {
|
|
||||||
toastStore.onToast('수정이 완료 되었습니다.', 's');
|
|
||||||
closeEditModal();
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getProjectList();
|
await getProjectList();
|
||||||
await userStore.userInfo();
|
await userStore.userInfo();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user