Files
egbim_homepage/egbim/skin/member/basic/mypage03.skin.php
T
2026-07-24 13:37:18 +09:00

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>