/** * Hlthset.js * * 건강 관심분야 설정 기능을 관리하는 모듈 * 사용자가 건강 관심분야를 선택하고 저장하여 맞춤 정보 및 마일리지를 받을 수 있는 기능 구현 */ $(document).ready(function() { // 전역 변수 - 관심분야 목록 데이터 var interestAreas = []; // 전역 변수 - 기본 정보 (마일리지 등) var basicInfo = {}; // 전역 변수 - 혜택 고유 번호 var bnfInnb = null; // CDN URL (JSP에서 전달받은 값 사용) var cdnUrl = '${cdnurl}'; /** * 관심건강분야 설정 정보 조회 함수 * 서버에서 관심분야 목록 데이터를 가져옴 */ function loadHealthInterestInfo() { console.log('=== loadHealthInterestInfo 시작 ==='); // 서버 API 호출 - 빈 값 또는 null로 요청 $.ajax({ url: '/sopmal/bnft/selectHealthInterestInfo', // 관심건강분야 설정 정보 조회 API method: 'POST', // HTTP 메서드 contentType: 'application/json', // 요청 콘텐츠 타입 data: JSON.stringify({}), // 빈 객체로 요청 beforeSend: function() { console.log('API 요청 시작 - URL:', '/sopmal/bnft/selectHealthInterestInfo'); console.log('요청 데이터:', {}); }, success: function(response) { console.log('=== API 응답 성공 ==='); console.log('전체 응답 데이터:', response); try { // 응답에서 관심분야 데이터 추출 및 전역 변수에 저장 if (response && response.resBody && response.resBody.result) { // JSON 문자열을 파싱 const resultData = JSON.parse(response.resBody.result); console.log('파싱된 resultData:', resultData); // 기본 정보 (마일리지, 이벤트 설명 등) 저장 if (resultData.basicInfo) { basicInfo = resultData.basicInfo; console.log('기본 정보:', basicInfo); // bnfInnb 값을 전역 변수에 저장 if (basicInfo.bnfInnb) { bnfInnb = basicInfo.bnfInnb; console.log('bnfInnb 값 설정:', bnfInnb); } // 마일리지 정보 화면에 업데이트 updateMileageDisplay(basicInfo.mlgRwdAmt); // 이벤트 설명 화면에 업데이트 updateEventDescription(basicInfo.bnfWordsCn); // 동의 여부에 따라 체크박스 상태 설정 updateAgreementCheckbox(basicInfo.agreAt); } // 관심분야 데이터 처리 if (resultData.interestAreas && resultData.interestAreas.length > 0) { console.log('관심분야 개수:', resultData.interestAreas.length); // 서버 데이터를 클라이언트에서 사용할 형태로 변환 (choiseAt 포함) interestAreas = resultData.interestAreas.map(function(item, index) { console.log(`관심분야 ${index + 1}:`, item); const mappedItem = { id: item.bnfIntrstInnb, // 관심분야 ID name: item.intrstNm, // 관심분야 이름 beforeImageUrl: window.cdnUrl + item.bfeImgFilCours, // 이미지 URL sortOrder: item.sortOrdr, // 정렬 순서 choiseAt: item.choiseAt || 'N' // 사용자 선택 여부 (기본값 N) }; console.log(`변환된 관심분야 ${index + 1}:`, mappedItem); return mappedItem; }); console.log('변환 완료된 interestAreas:', interestAreas); // 정렬 순서대로 정렬 interestAreas.sort(function(a, b) { return a.sortOrder - b.sortOrder; }); console.log('정렬 완료된 interestAreas:', interestAreas); } else { console.warn('관심분야 데이터가 없습니다.'); interestAreas = []; } } else { console.warn('응답 구조가 올바르지 않습니다.'); interestAreas = []; } } catch (e) { console.error('응답 데이터 파싱 실패:', e); interestAreas = []; } console.log('최종 interestAreas:', interestAreas); console.log('최종 bnfInnb:', bnfInnb); // 관심분야 목록 렌더링 console.log('renderInterestList 호출 시작'); renderInterestList(); // 사용자 선택 상태로 UI 업데이트 (choiseAt 값 활용) console.log('updateUIWithUserInterests 호출 시작'); updateUIWithUserInterests(interestAreas); console.log('=== loadHealthInterestInfo 완료 ==='); }, error: function(xhr, status, error) { console.error('=== API 호출 실패 ==='); console.error('xhr:', xhr); console.error('status:', status); console.error('error:', error); showToast('관심분야 정보를 불러오는데 실패했습니다.'); // 오류 발생 시 빈 배열로 초기화하여 에러 방지 interestAreas = []; renderInterestList(); } }); } /** * 마일리지 표시 업데이트 함수 * 화면의 마일리지 관련 텍스트를 동적으로 업데이트 * @param {number} mileageAmount - 마일리지 금액 */ function updateMileageDisplay(mileageAmount) { if (mileageAmount && mileageAmount > 0) { // 정수로 변환하여 표시 const mileageInt = Math.floor(mileageAmount); console.log('마일리지 업데이트:', mileageInt); // 상단 마일리지 안내 텍스트 업데이트 $('.topupPoint.noSticky span').html( '정보받기 동의하고 저장하면 ' + mileageInt.toLocaleString() + ' 원적립' ); } } /** * 이벤트 설명 업데이트 함수 * 화면의 이벤트 설명 텍스트를 동적으로 업데이트 * @param {string} eventDescription - 이벤트 설명 내용 (HTML 형태) */ function updateEventDescription(eventDescription) { if (eventDescription) { console.log('이벤트 설명 업데이트:', eventDescription); // 이벤트 설명 HTML 업데이트 (.text() 대신 .html() 사용) $('.comment-box p:last-child').html(eventDescription); } else { console.log('이벤트 설명이 없습니다.'); // 설명이 없는 경우 기본 메시지 표시 (텍스트는 .text() 사용) $('.comment-box p:last-child').text('이벤트 설명을 불러오는 중입니다...'); } } /** * UI 업데이트 함수 * 관심분야 데이터의 choiseAt 값으로 UI 상태 업데이트 * @param {Array} interests - 관심분야 배열 (choiseAt 포함) */ function updateUIWithUserInterests(interests) { // 모든 관심분야 항목 선택 해제 (초기화) $('.favoriteList li').removeClass('on'); // choiseAt이 'Y'인 관심분야를 선택 상태로 변경 interests.forEach(function(interest) { if (interest.choiseAt === 'Y') { // 관심분야 ID로 매칭되는 요소 찾아 선택 상태로 설정 $('.favoriteList li img[data-interest-id="' + interest.id + '"]') .closest('li') .addClass('on'); console.log('Selected interest:', interest.name, 'ID:', interest.id); } }); } /** * 관심분야 목록 렌더링 함수 * 서버에서 받아온 관심분야 데이터를 화면에 동적으로 표시 */ function renderInterestList() { const $favoriteList = $('.favoriteList'); // 관심분야 목록을 표시할 컨테이너 $favoriteList.empty(); // 기존 목록 초기화 (중복 방지) // 관심분야 데이터가 없는 경우 처리 if (!interestAreas || interestAreas.length === 0) { $favoriteList.append('
관심분야 정보를 불러오는 중입니다...
').addClass('img'); // 이미지 컨테이너
const $img = $('') // 이미지 요소
.attr('src', interest.beforeImageUrl) // 초기 이미지 URL
.attr('alt', interest.name) // 대체 텍스트
.attr('data-interest-id', interest.id); // 관심분야 ID 데이터 속성
const $titleP = $('
').addClass('tit').text(interest.name); // 관심분야 이름 요소 // 요소들 조합하여 DOM에 추가 $imgP.append($img); // 이미지를 이미지 컨테이너에 추가 $a.append($imgP).append($titleP); // 컨테이너와 제목을 링크에 추가 $li.append($a); // 링크를 리스트 아이템에 추가 $favoriteList.append($li); // 완성된 아이템을 목록에 추가 }); // 클릭 이벤트 리스너 추가 - 관심분야 선택/해제 토글 $('.favoriteList li a').on('click', function(e) { e.preventDefault(); // 기본 링크 동작 방지 $(this).closest('li').toggleClass('on'); // 선택 상태 토글 (선택: on 클래스 추가) }); } // 초기 로딩 함수 호출 loadHealthInterestInfo(); /** * 동의 체크박스 상태 업데이트 함수 * 서버에서 받아온 동의 여부에 따라 체크박스 상태를 설정 * @param {string} agreementStatus - 동의 여부 ('Y' 또는 'N') */ function updateAgreementCheckbox(agreementStatus) { const $agreementCheckbox = $('#agreementCheckbox'); if (agreementStatus === 'Y') { // 동의 상태인 경우 체크박스 체크 $agreementCheckbox.prop('checked', true); console.log('동의 상태로 체크박스 설정: Y'); } else { // 비동의 상태인 경우 체크박스 해제 $agreementCheckbox.prop('checked', false); console.log('비동의 상태로 체크박스 설정: N'); } } /** * 저장 버튼 클릭 이벤트 핸들러 * 선택된 관심분야와 동의 여부 확인 후 서버에 저장 요청 */ $('#saveBtn').on('click', function() { // bnfInnb 값이 없으면 저장 불가 if (!bnfInnb) { showToast('데이터 로딩 중입니다. 잠시 후 다시 시도해주세요.'); console.error('bnfInnb 값이 없어서 저장할 수 없습니다.'); return; } // 동의 체크박스 상태 확인 var agreementChecked = $('#agreementCheckbox').is(':checked'); // 동의 체크박스 미선택 시 알림 if (!agreementChecked) { showToast('관심분야 정보받기에 동의해주세요.'); return; } // 선택된 관심분야 정보 수집 - on 클래스가 있는 항목만 필터링 var selectedInterests = $('.favoriteList li.on').map(function() { return { bnfIntrstInnb: $(this).find('img').data('interest-id'), // 관심분야 ID selected: true // 선택 여부 }; }).get(); // jQuery 객체를 일반 배열로 변환 // 최소 1개 이상의 관심분야 선택 여부 확인 if (selectedInterests.length === 0) { showToast('최소 1개 이상의 관심분야를 선택해주세요.'); return; } // 서버로 전송할 데이터 준비 var data = { bnfInnb: bnfInnb, // 전역 변수 사용 interestAreas: selectedInterests, // 선택된 관심분야 목록 agreAt: agreementChecked ? 'Y' : 'N' // 동의 여부를 Y/N으로 변환 }; console.log('저장할 데이터:', data); // 디버깅용 로그 // 관심분야 저장 API 호출 $.ajax({ url: '/sopmal/bnft/saveUserInterests', // 관심분야 저장 API method: 'POST', // HTTP 메서드 contentType: 'application/json', // 요청 콘텐츠 타입 data: JSON.stringify(data), // 요청 데이터 success: function(response) { // 응답 데이터 파싱 const result = JSON.parse(response.resBody.result); if (result.success) { // 저장 성공 시 알림 표시 showToast(result.message); // 마일리지 적립 여부 확인 및 처리 if (result.mileageAccumulated && result.mlgRwdAmt) { const mileageAmount = Math.floor(result.mlgRwdAmt); showToast('마일리지 ' + mileageAmount.toLocaleString() + '원이 적립되었습니다.'); } // 사용자 관심분야 정보 다시 로드하여 UI 갱신 loadHealthInterestInfo(); } else { // 저장 실패 시 오류 메시지 표시 showToast('저장 중 오류가 발생했습니다: ' + result.message); } }, error: function(xhr, status, error) { // 통신 오류 처리 showToast('서버와의 통신 중 오류가 발생했습니다.'); console.error('Error:', error); } }); }); /** * 토스트 메시지 표시 함수 * 사용자에게 일시적인 알림 메시지 표시 * @param {string} message - 표시할 메시지 내용 */ function showToast(message) { var $toastPop = $('#toastPop'); // 토스트 팝업 요소 $toastPop.find('.txt').text(message); // 메시지 설정 $toastPop.addClass('show'); // 토스트 표시 // 2초 후 토스트 메시지 자동 숨김 setTimeout(function() { $toastPop.removeClass('show'); }, 2000); } });