478 lines
19 KiB
PHP
478 lines
19 KiB
PHP
<?php
|
|
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
|
|
include_once('./_common.php');
|
|
include_once __DIR__ . '/asset_urls.php';
|
|
|
|
$member = array_merge(array(
|
|
'mb_id' => '',
|
|
'mb_name' => '',
|
|
'mb_hp' => '',
|
|
'mb_comp' => '',
|
|
'mb_comp_team' => '',
|
|
), is_array($member) ? $member : array());
|
|
|
|
//add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css">', 0);
|
|
?>
|
|
|
|
<!--popup_wrap-->
|
|
<div class="popup_wrap" id="pop_mypage03">
|
|
<!--popup_in-->
|
|
<div class="popup_in">
|
|
<button class="btn_close">
|
|
<div class="close_div"><img src="<?php echo egbim_img_url('ico_close.svg'); ?>" alt=""></div>
|
|
</button>
|
|
<!--popup_content-->
|
|
<div class="popup_container mypage edit">
|
|
<!--pop_join_left-->
|
|
<div class="popup_tit">
|
|
<h1 class="h_1">마이페이지</h1>
|
|
<!-- <h3 class="h_3">
|
|
소중한 <em>내 정보</em>를 <br>
|
|
<em>최신</em>으로 관리하세요.
|
|
</h3> -->
|
|
</div>
|
|
<!--//pop_join_right-->
|
|
<div class="popup_contents_wrap">
|
|
<fieldset>
|
|
<!--tbl_wrap-->
|
|
<div id="register_form" class="tbl_wrap" style="height: 400px;">
|
|
<table>
|
|
<tbody>
|
|
<tr>
|
|
<th class="h_4">아이디</th>
|
|
<td>
|
|
<div class="id_wrap">
|
|
<input type="text" class="full_input" id="show_mb_id" name="mb_id" value="<?php echo $member['mb_id'] ?>" readonly style="color: #9aa0a6;">
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th class="h_4">사번</th>
|
|
<td>
|
|
<div class="password_wrap">
|
|
<input type="text" name="mb_password" id="show_mb_employeeid" class="frm_input full_input" data-editable>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th class="h_4">이름</th>
|
|
<td>
|
|
<div class="name_wrap">
|
|
<input type="text" id="show_mb_name" name="mb_name" value="<?php echo get_text($member['mb_name']) ?>" class="frm_input full_input" data-editable>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th class="h_4">직위</th>
|
|
<td>
|
|
<div class="position_wrap">
|
|
<input type="text" id="show_mb_position" name="mb_position" class="frm_input full_input" data-editable>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th class="h_4">휴대전화번호</th>
|
|
<td>
|
|
<div class="phone_wrap">
|
|
<input type="text" name="mb_hp" value="<?php echo preg_replace("/[^0-9]*/s", "", $member['mb_hp']); ?>" id="show_mb_hp" class="frm_input full_input" data-editable>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr id="row_company">
|
|
<th class="h_4">회사정보</th>
|
|
<td>
|
|
<div class="company_wrap">
|
|
<input type="text" name="mb_comp" value="<?php echo get_text($member['mb_comp'])?>" id="show_mb_comp" class="frm_input" data-editable>
|
|
<input type="text" name="mb_comp_team" value="<?php echo get_text($member['mb_comp_team'])?>" id="show_mb_comp_team" class="frm_input" data-editable>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr id="row_team_external" style="display:none;">
|
|
<th class="h_4">소속부서</th>
|
|
<td>
|
|
<div class="team_wrap">
|
|
<input type="text" name="mb_comp_team_ext" id="show_mb_comp_team_ext" class="frm_input" data-editable placeholder="소속부서">
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="btn_confirm">
|
|
<!-- <button type="button" onclick="mypage02();" class="btn_cancel">취소</button> -->
|
|
<button type="button" id="btn_profile_edit" class="btn_submit" >정보수정</button>
|
|
</div>
|
|
<div class="sign_out">
|
|
<a href="#" id="btn_delete_account"><i class="signout"></i>회원 탈퇴하기</a>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!--//pop_join_right-->
|
|
</div>
|
|
<!--//popup_content-->
|
|
</div>
|
|
<!--//popup_in-->
|
|
</div>
|
|
<!--//popup_wrap-->
|
|
|
|
<script>
|
|
(function () {
|
|
// === 설정 ===
|
|
const INTERNAL_DOMAINS = [
|
|
"hanmaceng.co.kr","samaneng.com","jangheon.co.kr",
|
|
"hallasanup.com","pre-cast.co.kr","baroncs.co.kr"
|
|
];
|
|
const MAX_LOGINID_RETRY = 5;
|
|
|
|
// === 상태 ===
|
|
let loginIdRetryCount = 0;
|
|
|
|
// === 엘리먼트 캐시 ===
|
|
const $btn = $('#pop_mypage03 #btn_profile_edit');
|
|
const $edit = $('[data-editable]');
|
|
|
|
const $id = $('#show_mb_id'); // 아이디(=이메일, readonly)
|
|
const $empId = $('#show_mb_employeeid'); // 사번(내부)
|
|
const $name = $('#show_mb_name'); // 이름
|
|
const $pos = $('#show_mb_position'); // 직위(내부)
|
|
const $phone = $('#show_mb_hp'); // 휴대전화
|
|
const $comp = $('#show_mb_comp'); // 내부=가족사, 외부=회사명
|
|
const $team = $('#show_mb_comp_team'); // 소속부서(내/외 공통)
|
|
|
|
const $rowEmp = $empId.closest('tr');
|
|
const $rowPos = $pos.closest('tr');
|
|
const $rowCompany = $('#row_company'); // 회사정보 행
|
|
|
|
// === 전화번호 포맷/검증 ===
|
|
function autoHyphen010(inputEl) {
|
|
let v = inputEl.value.replace(/\D/g, '').slice(0, 11); // 숫자만 11자리까지
|
|
if (v.length < 4) { inputEl.value = v; return; }
|
|
if (!v.startsWith('010')) { inputEl.value = v; return; }
|
|
if (v.length <= 7) {
|
|
inputEl.value = v.slice(0,3) + '-' + v.slice(3);
|
|
} else {
|
|
inputEl.value = v.slice(0,3) + '-' + v.slice(3,7) + '-' + v.slice(7);
|
|
}
|
|
}
|
|
function isValidPhone010(str) {
|
|
return /^010-\d{4}-\d{4}$/.test((str||'').trim());
|
|
}
|
|
|
|
// === 유틸 ===
|
|
function isInternal(email) {
|
|
if (!email) return false;
|
|
const domain = (email.split('@')[1] || '').toLowerCase();
|
|
return INTERNAL_DOMAINS.includes(domain);
|
|
}
|
|
function getEmailFromUI() {
|
|
return ($id.val() || sessionStorage.getItem('loginId') || '').trim();
|
|
}
|
|
function showHint($input, msg) {
|
|
clearHint($input);
|
|
$input.addClass('input-error').after('<span class="field-hint">'+msg+'</span>');
|
|
}
|
|
function clearHint($input) {
|
|
$input.removeClass('input-error').siblings('.field-hint').remove();
|
|
}
|
|
function clearAllHints() {
|
|
$edit.each(function(){ clearHint($(this)); });
|
|
}
|
|
|
|
// === 내부/외부 UI 토글 ===
|
|
function applyTenantUI(email) {
|
|
const internal = isInternal(email);
|
|
|
|
if (internal) {
|
|
$rowEmp.show();
|
|
$rowPos.show();
|
|
$rowCompany.show();
|
|
|
|
// ✅ 회사명 → 아이디와 동일한 스타일
|
|
$comp
|
|
.prop('readonly', true)
|
|
.css('color', '#9aa0a6')
|
|
.css('background-color', 'transparent') // 🔑 핵심
|
|
.attr('placeholder', '가족사');
|
|
|
|
// 소속부서는 편집 가능
|
|
$team
|
|
.prop('readonly', false)
|
|
.css('color', '')
|
|
.css('background-color', '')
|
|
.attr('placeholder', '소속부서');
|
|
|
|
} else {
|
|
$rowEmp.hide().find('input').val('');
|
|
$rowPos.hide().find('input').val('');
|
|
$rowCompany.show();
|
|
|
|
// 외부 사용자 → 입력 가능
|
|
$comp
|
|
.prop('readonly', false)
|
|
.css('color', '')
|
|
.css('background-color', '') // 원복
|
|
.attr('placeholder', '회사명');
|
|
|
|
$team
|
|
.prop('readonly', false)
|
|
.css('color', '')
|
|
.css('background-color', '')
|
|
.attr('placeholder', '소속부서');
|
|
}
|
|
}
|
|
|
|
// === 검증 ===
|
|
function validate() {
|
|
clearAllHints();
|
|
const name = ($name.val() || '').trim();
|
|
const phone = ($phone.val() || '').trim();
|
|
const email = getEmailFromUI();
|
|
const internal = isInternal(email);
|
|
|
|
let ok = true;
|
|
if (!name) showHint($name, '이름을 입력해 주세요.'), ok = false;
|
|
if (!/^[0-9\-]{9,15}$/.test(phone)) showHint($phone, '숫자(하이픈 가능) 9~15자리로 입력해 주세요.'), ok = false;
|
|
|
|
if (internal) {
|
|
if (!($pos.val() || '').trim()) showHint($pos, '직위를 입력해 주세요.'), ok = false;
|
|
if (!($comp.val() || '').trim()) showHint($comp, '가족사를 입력해 주세요.'), ok = false;
|
|
if (!($team.val() || '').trim()) showHint($team, '소속부서를 입력해 주세요.'), ok = false;
|
|
if (!($empId.val()|| '').trim()) showHint($empId,'사번을 입력해 주세요.'), ok = false;
|
|
} else {
|
|
if (!($comp.val() || '').trim()) showHint($comp, '회사명을 입력해 주세요.'), ok = false;
|
|
if (!($team.val() || '').trim()) showHint($team, '소속부서를 입력해 주세요.'), ok = false;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
// === 저장 ===
|
|
function saveProfile() {
|
|
if (!validate()) return;
|
|
|
|
// const refreshJwt = sessionStorage.getItem('refreshJwt') || '';
|
|
// if (!refreshJwt) { alert('인증 정보가 만료되었습니다. 다시 로그인해 주세요.'); return; }
|
|
|
|
const email = getEmailFromUI();
|
|
const internal = isInternal(email);
|
|
|
|
const payload = {
|
|
email, // loginId
|
|
name: ($name.val() || '').trim(),
|
|
phone: ($phone.val() || '').trim(),
|
|
position: ($pos.val() || '').trim(), // 외부여도 전송 무해
|
|
completeForm: true
|
|
};
|
|
|
|
if (internal) {
|
|
payload.familyCompany = ($comp.val() || '').trim(); // 가족사
|
|
payload.team = ($team.val() || '').trim(); // 소속부서
|
|
payload.familyUniqueKey = ($empId.val() || '').trim(); // 사번
|
|
payload.employeeId = payload.familyUniqueKey; // 호환 키
|
|
} else {
|
|
payload.company = ($comp.val() || '').trim(); // 회사명
|
|
payload.team = ($team.val() || '').trim(); // 소속부서
|
|
}
|
|
|
|
$.ajax({
|
|
url: '/egbim/skin/member/basic/descope_update.php',
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: payload,
|
|
beforeSend(){ $btn.prop('disabled', true).text('저장중…'); },
|
|
complete(){ $btn.prop('disabled', false).text('저장'); },
|
|
success(res){
|
|
if (res.status === 'ok') {
|
|
alert('정보가 저장되었습니다.');
|
|
closeMyPagePopup(); // ✅ 저장 성공 시 팝업 닫기
|
|
// 필요 시 전체 새고: location.reload();
|
|
} else {
|
|
alert(res.message || '저장에 실패했습니다.');
|
|
}
|
|
},
|
|
error(xhr){
|
|
alert('서버 오류: ' + (xhr.statusText||'') + '\n' + (xhr.responseText||''));
|
|
}
|
|
});
|
|
}
|
|
|
|
// === 팝업 닫기 ===
|
|
function closeMyPagePopup() {
|
|
// 닫기 버튼이 자체 로직을 가지고 있으면 그걸 트리거하는 게 가장 안전
|
|
const $closeBtn = $('#pop_mypage03 .btn_close');
|
|
if ($closeBtn.length) {
|
|
$closeBtn.trigger('click');
|
|
} else {
|
|
// 폴백: 직접 숨김 처리
|
|
$('#pop_mypage03').hide();
|
|
$('body').css('overflow','');
|
|
}
|
|
}
|
|
|
|
// === 이벤트 바인딩 ===
|
|
// 입력칸 항상 편집 가능 + 버튼은 항상 "저장"
|
|
$edit.prop('readonly', false);
|
|
$btn.text('저장');
|
|
|
|
// 전화번호 입력 바인딩(중복 방지)
|
|
$phone.off('.hp');
|
|
let hpWarnedOnce = false;
|
|
$phone
|
|
.on('input.hp', function () {
|
|
autoHyphen010(this);
|
|
hpWarnedOnce = false; // 다시 입력하면 경고 플래그 해제
|
|
})
|
|
.on('paste.hp', function () {
|
|
const el = this;
|
|
setTimeout(function(){ autoHyphen010(el); hpWarnedOnce = false; }, 0);
|
|
})
|
|
.on('blur.hp', function () {
|
|
const v = $(this).val().trim();
|
|
if (v && !isValidPhone010(v) && !hpWarnedOnce) {
|
|
hpWarnedOnce = true;
|
|
alert('휴대전화번호는 010-1234-5678 형식으로 입력해 주세요.');
|
|
setTimeout(() => { $phone.focus(); }, 0); // 즉시 focus는 blur 루프 유발
|
|
}
|
|
});
|
|
|
|
// 버튼: 바로 저장
|
|
$btn.off('click.mypage').on('click.mypage', function (e) {
|
|
e.preventDefault();
|
|
// 저장 직전 최종 포맷 체크 (한 번 더)
|
|
if (!isValidPhone010(($phone.val()||'').trim())) {
|
|
alert('휴대전화번호는 010-1234-5678 형식으로 입력해 주세요.');
|
|
$phone.focus();
|
|
return;
|
|
}
|
|
saveProfile(); // ✅ 한 번 클릭으로 바로 저장
|
|
});
|
|
|
|
// 탈퇴 버튼 클릭 → 삭제 함수 호출
|
|
$(document).on('click', '#btn_delete_account', function(e){
|
|
e.preventDefault();
|
|
deleteDescopeUser();
|
|
});
|
|
|
|
// === customAttributes 안전 접근 ===
|
|
function ca(u, keys) {
|
|
for (const k of keys) {
|
|
const v = u && u.customAttributes && u.customAttributes[k];
|
|
if (v !== undefined && v !== null && String(v).length) return v;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
// === 사용자 조회 ===
|
|
function loadDescopeUser() {
|
|
const loginId = sessionStorage.getItem('loginId');
|
|
if (!loginId) {
|
|
if (loginIdRetryCount < MAX_LOGINID_RETRY) {
|
|
loginIdRetryCount++;
|
|
return setTimeout(loadDescopeUser, 150 * Math.pow(2, loginIdRetryCount - 1));
|
|
}
|
|
return;
|
|
}
|
|
loginIdRetryCount = 0;
|
|
|
|
$.ajax({
|
|
url: '/egbim/skin/member/basic/descope_user_search.php',
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: { loginId },
|
|
// timeout: 8000,
|
|
success(res) {
|
|
if (!(res.status === 'ok' && res.user)) { alert('사용자 정보를 불러올 수 없습니다.'); return; }
|
|
const u = res.user;
|
|
|
|
const email = (u.loginIds && u.loginIds[0]) ? u.loginIds[0] : (u.email || loginId);
|
|
$id.val(email);
|
|
$name.val(u.name || '');
|
|
$phone.val(u.phone || '');
|
|
$pos.val(ca(u, ['position']) || '');
|
|
|
|
// 공통값
|
|
$comp.val(ca(u, ['familyCompany','company']) || '');
|
|
$team.val(ca(u, ['team']) || '');
|
|
$empId.val(isInternal(email) ? (ca(u, ['familyUniqueKey','employeeId']) || '') : '');
|
|
|
|
// UI 분기
|
|
applyTenantUI(email);
|
|
|
|
// 탈퇴용 ID 저장
|
|
if (u.userId) sessionStorage.setItem('descopeUserId', u.userId);
|
|
},
|
|
error(xhr) {
|
|
alert('서버 통신 오류: ' + (xhr.statusText || ''));
|
|
}
|
|
});
|
|
}
|
|
|
|
// === 외부에서 로그인 성공 시 호출됨 ===
|
|
window.onLoginSuccess = function (loginId, sessionJwt, refreshJwt) {
|
|
if (loginId) sessionStorage.setItem('loginId', loginId);
|
|
if (sessionJwt) sessionStorage.setItem('sessionJwt', sessionJwt);
|
|
if (refreshJwt) sessionStorage.setItem('refreshJwt', refreshJwt);
|
|
loadDescopeUser();
|
|
};
|
|
|
|
// === 팝업 표시될 때마다 갱신 ===
|
|
const popupEl = document.getElementById('pop_mypage03');
|
|
if (popupEl) {
|
|
new MutationObserver((muts) => {
|
|
muts.forEach((m) => {
|
|
if (m.type === 'attributes' && (m.attributeName === 'style' || m.attributeName === 'class')) {
|
|
const visible = $('#pop_mypage03').is(':visible') || $('#pop_mypage03').css('display') !== 'none';
|
|
if (visible) {
|
|
setTimeout(() => {
|
|
loadDescopeUser();
|
|
const email = getEmailFromUI();
|
|
if (email) applyTenantUI(email);
|
|
}, 50);
|
|
}
|
|
}
|
|
});
|
|
}).observe(popupEl, { attributes: true, attributeFilter: ['style','class'] });
|
|
}
|
|
|
|
// === 최초 진입 ===
|
|
document.addEventListener('DOMContentLoaded', loadDescopeUser);
|
|
|
|
// === 탈퇴 ===
|
|
window.deleteDescopeUser = function () {
|
|
// 폴백: sessionStorage → 입력칸
|
|
const userId = sessionStorage.getItem('descopeUserId') || '';
|
|
const uiLogin = ($('#show_mb_id').val() || '').trim();
|
|
const loginId = sessionStorage.getItem('loginId') || uiLogin;
|
|
|
|
if (!userId && !loginId) return alert('대상 정보가 없습니다. 다시 로그인 후 시도해 주세요.');
|
|
if (!confirm('정말 탈퇴하시겠습니까? 이 작업은 되돌릴 수 없습니다.')) return;
|
|
|
|
$.ajax({
|
|
url: '/egbim/skin/member/basic/descope_user_delete.php',
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: { userId, loginId },
|
|
success(res) {
|
|
if (res.status === 'ok') {
|
|
alert('정상적으로 탈퇴되었습니다.');
|
|
// 🔑 sessionStorage 완전 초기화
|
|
sessionStorage.clear();
|
|
localStorage.clear();
|
|
location.reload();
|
|
} else {
|
|
alert('탈퇴 실패: ' + (res.message || '알 수 없는 오류'));
|
|
}
|
|
},
|
|
error(xhr) {
|
|
alert('서버 오류로 탈퇴 실패: ' + (xhr.statusText || ''));
|
|
}
|
|
});
|
|
};
|
|
})();
|
|
</script>
|
|
|
|
|