마이페이지
This commit is contained in:
parent
a5fe714c73
commit
c60bed282f
@ -16,67 +16,26 @@
|
||||
|
||||
<div class="col-xl-12">
|
||||
<div class="d-flex">
|
||||
<UserFormInput
|
||||
title="입사일"
|
||||
name="entryDate"
|
||||
type="date"
|
||||
:value="form.entryDate"
|
||||
@update:data="form.entryDate = $event"
|
||||
class="me-2 w-50"
|
||||
/>
|
||||
<FormSelect
|
||||
title="컬러"
|
||||
name="color"
|
||||
:is-row="false"
|
||||
:is-label="true"
|
||||
:is-common="true"
|
||||
:is-color="true"
|
||||
:data="colorList"
|
||||
:value="form.color"
|
||||
@update:data="handleColorUpdate"
|
||||
class="w-50"
|
||||
/>
|
||||
<UserFormInput title="입사일" name="entryDate" type="date"
|
||||
:value="form.entryDate" @update:data="form.entryDate = $event" class="me-2 w-50" />
|
||||
<FormSelect title="컬러" name="color" :is-row="false" :is-label="true"
|
||||
:is-common="true" :is-color="true" :data="colorList"
|
||||
:value="form.color" @update:data="handleColorUpdate" class="w-50" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex">
|
||||
<UserFormInput
|
||||
title="생년월일"
|
||||
name="birth"
|
||||
type="date"
|
||||
:value="form.birth"
|
||||
@update:data="form.birth = $event"
|
||||
class="me-2 w-50"
|
||||
/>
|
||||
<FormSelect
|
||||
title="MBTI"
|
||||
name="mbti"
|
||||
:is-row="false"
|
||||
:is-label="true"
|
||||
:is-common="true"
|
||||
:is-mbti="true"
|
||||
:data="mbtiList"
|
||||
:value="form.mbti"
|
||||
@update:data="form.mbti = $event"
|
||||
class="w-50"
|
||||
/>
|
||||
<UserFormInput title="생년월일" name="birth" type="date"
|
||||
:value="form.birth" @update:data="form.birth = $event" class="me-2 w-50" />
|
||||
<FormSelect title="MBTI" name="mbti" :is-row="false" :is-label="true"
|
||||
:is-common="true" :is-mbti="true" :data="mbtiList"
|
||||
:value="form.mbti" @update:data="form.mbti = $event" class="w-50" />
|
||||
</div>
|
||||
|
||||
<ArrInput
|
||||
title="주소"
|
||||
name="address"
|
||||
v-model="form.address"
|
||||
:disabled="true"
|
||||
/>
|
||||
<ArrInput title="주소" name="address" v-model="form.address" :disabled="true" />
|
||||
|
||||
<UserFormInput
|
||||
title="휴대전화"
|
||||
name="phone"
|
||||
:value="form.phone"
|
||||
@update:data="form.phone = $event"
|
||||
@blur="checkPhoneDuplicate"
|
||||
:maxlength="11"
|
||||
@keypress="onlyNumber"
|
||||
/>
|
||||
<UserFormInput title="전화번호" name="phone" :value="form.phone"
|
||||
@update:data="form.phone = $event" @blur="checkPhoneDuplicate"
|
||||
:maxlength="11" @keypress="onlyNumber" />
|
||||
|
||||
<div class="d-flex mt-5">
|
||||
<button type="submit" class="btn btn-primary w-100" :disabled="!isChanged">
|
||||
@ -98,26 +57,21 @@ import ArrInput from '@c/input/ArrInput.vue';
|
||||
import { useToastStore } from '@s/toastStore';
|
||||
|
||||
const toastStore = useToastStore();
|
||||
const originalData = ref({});
|
||||
const form = ref({
|
||||
entryDate: '',
|
||||
birth: '',
|
||||
address: {
|
||||
address: '',
|
||||
detailAddress: '',
|
||||
postcode: ''
|
||||
},
|
||||
phone: '',
|
||||
color: '',
|
||||
mbti: ''
|
||||
});
|
||||
|
||||
const form = ref({
|
||||
entryDate: '',
|
||||
birth: '',
|
||||
address: { address: '', detailAddress: '', postcode: '' },
|
||||
phone: '',
|
||||
color: '',
|
||||
mbti: ''
|
||||
});
|
||||
const originalData = ref({});
|
||||
const profile = ref('');
|
||||
const uploadedFile = ref(null);
|
||||
const profileChanged = ref(false);
|
||||
const profilerr = ref('');
|
||||
const currentBlobUrl = ref('');
|
||||
|
||||
const colorDuplicated = ref(false);
|
||||
const phoneDuplicated = ref(false);
|
||||
const mbtiList = ref([]);
|
||||
@ -126,8 +80,7 @@ const colorList = ref([]);
|
||||
const isChanged = computed(() => {
|
||||
const f = form.value;
|
||||
const o = originalData.value;
|
||||
|
||||
const baseChanged =
|
||||
return (
|
||||
f.entryDate !== o.entryDate ||
|
||||
f.birth !== o.birth ||
|
||||
f.phone !== o.phone ||
|
||||
@ -135,131 +88,152 @@ const isChanged = computed(() => {
|
||||
f.mbti !== o.mbti ||
|
||||
f.address.address !== o.address.address ||
|
||||
f.address.detailAddress !== o.address.detailAddress ||
|
||||
f.address.postcode !== o.address.postcode;
|
||||
|
||||
return baseChanged || profileChanged.value;
|
||||
f.address.postcode !== o.address.postcode ||
|
||||
profileChanged.value
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, "");
|
||||
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
||||
const defaultProfile = "img/avatars/default-Profile.jpg";
|
||||
|
||||
const getProfileImageUrl = (fileName) => {
|
||||
return fileName && fileName.trim()
|
||||
return fileName?.trim()
|
||||
? `${baseUrl}upload/img/profile/${fileName}?t=${Date.now()}`
|
||||
: defaultProfile;
|
||||
};
|
||||
|
||||
const profilePreviewStyle = computed(() => {
|
||||
return {
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
backgroundImage: `url(${profile.value})`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center'
|
||||
};
|
||||
});
|
||||
const profilePreviewStyle = computed(() => ({
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
backgroundImage: `url(${profile.value})`,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center'
|
||||
}));
|
||||
|
||||
const profileUpload = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (file.size > 5 * 1024 * 1024 || !['image/jpeg', 'image/png'].includes(file.type)) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
if (file.size > 5 * 1024 * 1024 || !['image/jpeg', 'image/png'].includes(file.type)) {
|
||||
profilerr.value = '5MB 이하의 JPG/PNG 파일만 업로드 가능합니다.';
|
||||
return;
|
||||
}
|
||||
|
||||
profilerr.value = '';
|
||||
|
||||
// 기존 blob 주소 해제
|
||||
if (currentBlobUrl.value) {
|
||||
URL.revokeObjectURL(currentBlobUrl.value);
|
||||
}
|
||||
|
||||
uploadedFile.value = file;
|
||||
const newBlobUrl = URL.createObjectURL(file);
|
||||
profile.value = newBlobUrl;
|
||||
currentBlobUrl.value = newBlobUrl;
|
||||
profileChanged.value = true;
|
||||
};
|
||||
|
||||
const checkPhoneDuplicate = async () => {
|
||||
const res = await $api.get('/user/checkPhone', { params: { memberTel: form.value.phone } });
|
||||
phoneDuplicated.value = !res.data.data;
|
||||
};
|
||||
|
||||
const handleColorUpdate = async (colorVal) => {
|
||||
form.value.color = colorVal;
|
||||
const res = await $api.get('/user/checkColor', { params: { memberCol: colorVal } });
|
||||
colorDuplicated.value = res.data.data;
|
||||
}
|
||||
profilerr.value = '';
|
||||
if (currentBlobUrl.value) URL.revokeObjectURL(currentBlobUrl.value);
|
||||
uploadedFile.value = file;
|
||||
const newBlobUrl = URL.createObjectURL(file);
|
||||
profile.value = newBlobUrl;
|
||||
currentBlobUrl.value = newBlobUrl;
|
||||
profileChanged.value = true;
|
||||
};
|
||||
|
||||
const onlyNumber = (e) => {
|
||||
if (!/[0-9]/.test(e.key)) e.preventDefault();
|
||||
if (!/[0-9]/.test(e.key)) e.preventDefault();
|
||||
};
|
||||
|
||||
const formatDate = (isoDate) => {
|
||||
return isoDate ? isoDate.split('T')[0] : '';
|
||||
const checkPhoneDuplicate = async () => {
|
||||
const res = await $api.get('/user/checkPhone', { params: { memberTel: form.value.phone } });
|
||||
phoneDuplicated.value = !res.data.data;
|
||||
};
|
||||
|
||||
const handleColorUpdate = async (colorVal) => {
|
||||
if (colorVal !== originalData.value.color) {
|
||||
const res = await $api.get('/user/checkColor', { params: { memberCol: colorVal } });
|
||||
if (res.data.data) {
|
||||
toastStore.onToast('이미 사용 중인 컬러입니다.', 'e');
|
||||
form.value.color = originalData.value.color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
form.value.color = colorVal;
|
||||
};
|
||||
|
||||
const formatDate = (isoDate) => (isoDate ? isoDate.split('T')[0] : '');
|
||||
|
||||
const loadInitialData = async () => {
|
||||
const userRes = await $api.get('/user/userInfo');
|
||||
const user = userRes.data.data;
|
||||
const initData = {
|
||||
const userRes = await $api.get('/user/userInfo');
|
||||
const user = userRes.data.data;
|
||||
|
||||
const colorRes = await $api.get('/user/color', { params: { type: 'YON' } });
|
||||
const serverColors = colorRes.data.data.map(c => ({
|
||||
value: c.CMNCODVAL,
|
||||
label: c.CMNCODNAM
|
||||
}));
|
||||
|
||||
const matchedColor = serverColors.find(c => c.label === user.usercolor);
|
||||
const colorCode = matchedColor ? matchedColor.value : user.color;
|
||||
const exists = serverColors.some(c => c.value === colorCode);
|
||||
colorList.value = exists ? serverColors : [{ value: colorCode, label: user.usercolor }, ...serverColors];
|
||||
|
||||
const initData = {
|
||||
entryDate: formatDate(user.isCdt),
|
||||
birth: formatDate(user.birth),
|
||||
address: {
|
||||
address: user.address || '',
|
||||
detailAddress: user.addressDetail || '',
|
||||
postcode: user.zipcode || ''
|
||||
address: user.address || '',
|
||||
detailAddress: user.addressDetail || '',
|
||||
postcode: user.zipcode || ''
|
||||
},
|
||||
phone: user.phone || '',
|
||||
color: user.color || '',
|
||||
color: colorCode,
|
||||
mbti: user.mbit || ''
|
||||
};
|
||||
};
|
||||
|
||||
form.value = { ...initData };
|
||||
originalData.value = { ...initData };
|
||||
form.value = { ...initData };
|
||||
originalData.value = { ...initData };
|
||||
|
||||
profile.value = getProfileImageUrl(user.profile);
|
||||
profileChanged.value = false;
|
||||
profile.value = getProfileImageUrl(user.profile);
|
||||
profileChanged.value = false;
|
||||
|
||||
const colorRes = await $api.get('/user/color', { params: { type: 'main' } });
|
||||
colorList.value = colorRes.data.data.map(c => ({ value: c.CMNCODVAL, label: c.CMNCODNAM }));
|
||||
|
||||
const mbtiRes = await $api.get('/user/mbti');
|
||||
mbtiList.value = mbtiRes.data.data.map(m => ({ value: m.CMNCODVAL, label: m.CMNCODNAM }));
|
||||
const mbtiRes = await $api.get('/user/mbti');
|
||||
mbtiList.value = mbtiRes.data.data.map(m => ({
|
||||
value: m.CMNCODVAL,
|
||||
label: m.CMNCODNAM
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const formData = new FormData();
|
||||
formData.append('entryDate', form.value.entryDate);
|
||||
formData.append('birth', form.value.birth);
|
||||
formData.append('phone', form.value.phone);
|
||||
formData.append('color', form.value.color);
|
||||
formData.append('mbti', form.value.mbti);
|
||||
formData.append('address', form.value.address.address);
|
||||
formData.append('detailAddress', form.value.address.detailAddress);
|
||||
formData.append('postcode', form.value.address.postcode);
|
||||
if (uploadedFile.value) {
|
||||
formData.append('profileFile', uploadedFile.value);
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append('entryDate', form.value.entryDate);
|
||||
formData.append('birth', form.value.birth);
|
||||
formData.append('phone', form.value.phone);
|
||||
formData.append('color', form.value.color);
|
||||
formData.append('mbti', form.value.mbti);
|
||||
formData.append('address', form.value.address.address);
|
||||
formData.append('detailAddress', form.value.address.detailAddress);
|
||||
formData.append('postcode', form.value.address.postcode);
|
||||
if (uploadedFile.value) formData.append('profileFile', uploadedFile.value);
|
||||
|
||||
await $api.patch('/user/updateInfo', formData, { isFormData: true });
|
||||
// 컬러 변경 시 업데이트
|
||||
if (form.value.color !== originalData.value.color) {
|
||||
if (form.value.color) {
|
||||
await $api.patch('/user/updateColorYon', {
|
||||
color: form.value.color,
|
||||
type: 'YON'
|
||||
});
|
||||
}
|
||||
if (originalData.value.color) {
|
||||
await $api.patch('/user/updateColorChange', {
|
||||
color: originalData.value.color,
|
||||
type: 'YON'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
originalData.value = { ...form.value };
|
||||
profileChanged.value = false;
|
||||
toastStore.onToast('정보가 수정되었습니다.', 's');
|
||||
await $api.patch('/user/updateInfo', formData, { isFormData: true });
|
||||
|
||||
originalData.value = { ...form.value };
|
||||
profileChanged.value = false;
|
||||
location.reload();
|
||||
toastStore.onToast('정보가 수정되었습니다.', 's');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadInitialData();
|
||||
loadInitialData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-red-500 {
|
||||
color: #f56565;
|
||||
color: #f56565;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user