(async () => { const { EventManager, pageHelper, utils } = ShopbySkin; const $offlineStoreImageList = $('offline-store-image-list'); // 오프라인 스토어 이미지 리스트 const $offlineStoreInfo = $('offline-store-info'); // 오프라인 스토어 정보 const $offlineStoreList = $('offline-store-list'); // 오프라인 스토어 리스트 const $offlineEventList = $('offline-event-list'); // 오프라인 이벤트 리스트 const $offlineStoreNotice = $('offline-store-notice'); // 오프라인 스토어 공지사항 let mapOption = {}; const wholeLat = '35.95'; const wholeLng = '128.25'; // [Aaron] 오프라인 매장 조회 API const param = { method: 'GET', data: { page: 1, take: 100, }, }; // 테스트용 - 에이샵 매장 Api 조회(임시) const { result: { data: storeData, statusCode: storeStatusCode }, } = await callGeekApi('/app/sbgolf-shop', param); storeData.forEach((data) => { data.additionalInfo = JSON.parse(data.additionalInfo); }); // [Jay] 메인 상단에 노출되는 매장은 직영점만 노출 // 직영점 : D, 프렌차이즈 : F const mainOfflineStoreData = storeData.filter( (data) => data.additionalInfo.storeType === 'D', ); // [Jay] 매장 리스트 직영점/프랜차이즈 순으로 정렬(각 정렬은 regDt asc 순으로 정렬) mainOfflineStoreData.sort((a, b) => { const storeTypeOrder = ['D', 'F']; const storeTypeA = storeTypeOrder.indexOf(a.additionalInfo.storeType); const storeTypeB = storeTypeOrder.indexOf(b.additionalInfo.storeType); if (storeTypeA !== storeTypeB) { return storeTypeA - storeTypeB; } return new Date(a.regDt) - new Date(b.regDt); }); const filteredShopData = mainOfflineStoreData .map((data) => { if ( data.additionalInfo && Array.isArray(data.additionalInfo.offlineStoreImage) ) { // offlineStoreImage에서 type이 'detail'인 것만 남기기 const filteredImages = data.additionalInfo.offlineStoreImage.filter( (image) => image.type === 'detail', ); // 필터링된 이미지가 있으면 해당 데이터를 반환 if (filteredImages.length > 0) { return { ...data, additionalInfo: { ...data.additionalInfo, offlineStoreImage: filteredImages, }, }; } } return null; // 조건에 맞지 않으면 제외 }) .filter((data) => data !== null); // null 값을 제거 // [Aaron] 오프라인 스토어 이미지 리스트 렌더 const offlineStoreImageListHtml = renderHtml( $offlineStoreImageList, filteredShopData, ); $offlineStoreImageList.append(offlineStoreImageListHtml); $offlineStoreImageList.velocity({ opacity: 1 }, { duration: 500 }); // END // [Aaron] 지역리스트 추출 const { result: cityList } = await callGeekApi('/app/common/city', { method: 'GET', }); const storeFilter = { storeType: ['D', 'F'], cityList, }; // [Aaron] 오프라인 스토어 리스트 렌더 const offlineStoreInfo = renderHtml($offlineStoreInfo, storeFilter); $offlineStoreInfo.append(offlineStoreInfo); // [Jay] 매장 리스트 직영점/프랜차이즈 순으로 정렬(각 정렬은 regDt asc 순으로 정렬) const sortedData = storeData.sort((a, b) => { const storeTypeOrder = ['D', 'F']; const storeTypeA = storeTypeOrder.indexOf(a.additionalInfo.storeType); const storeTypeB = storeTypeOrder.indexOf(b.additionalInfo.storeType); if (storeTypeA !== storeTypeB) { return storeTypeA - storeTypeB; } return new Date(a.regDt) - new Date(b.regDt); }); const offlineStoreList = renderHtml($offlineStoreList, sortedData); $offlineStoreInfo.find('.store__items').append(offlineStoreList); $offlineStoreInfo.velocity({ opacity: 1 }, { duration: 500 }); // END // [Aaron] 오프라인 리스트 첫번째 매장 카카오맵 실행 if (storeData.length > 0) { detailKakaoMap(storeData[0].sno, storeData[0].lat, storeData[0].lng); } else { // 등록된 스토어가 없을 경우 서울 중심 좌표 세팅 detailKakaoMap(null, wholeLat, wholeLng); } // [Aaron] 오프라인 이벤트 게시글 데이터 추출 및 렌더 const offlineEventsParams = { queryString: { pageNumber: 1, pageSize: 2, startYmd: '2024-11-07', }, }; const { result: offlineEventData } = await callShopApi( `/boards/${EVENT_PAGE_OFFLINE_BOARDID}/articles?`, 'GET', offlineEventsParams, ); const offlineEventList = renderHtml($offlineEventList, offlineEventData); $offlineEventList.append(offlineEventList); // END // [Aaron] 오프라인 스토어 공지사항 조회 및 렌더 const boardArticlesParams = { queryString: { pageNumber: 1, pageSize: 9, }, }; const boardId = 'offlineNotice'; const { result: offlineNoticeData, statusCode } = await callShopApi( `/boards/${boardId}/articles?`, 'GET', boardArticlesParams, ); // 게시판 ID로 게시판번호 추출 (게시판 상세 페이지이동을 위해 boardNo 값 필요) if (statusCode < 400) { const introHelper = pageHelper.introHelper(); const { boardsCategories } = await introHelper.getMalls(); const offlineBoard = boardsCategories.filter( (cate) => cate.boardId === boardId, ); offlineNoticeData.boardNo = offlineBoard[0].boardNo; } const offlineStoreNoticeHtml = renderHtml( $offlineStoreNotice, offlineNoticeData, ); $offlineStoreNotice.append(offlineStoreNoticeHtml); // END $('.offline-store__notify').velocity({ opacity: 1 }, { duration: 500 }); // [Aaron] 오프라인 리스트 클릭 이벤트 $('offline-store-info').on('click', '.store__item', onClickShopDetailView); // [Aaron] 매장 리스트 필터 이벤트 const changeEventListener = ({ target }) => { const storeItemsEl = $('.store__items'); let storeType = document.getElementById('storeType').value; let cityType = document.getElementById('cityType').value; let selectedStoreList = []; // [Jay] 매장타입이 전체인 경우 if (storeType === 'all') { if (cityType === 'all') { selectedStoreList = storeData; } else { selectedStoreList = storeData.filter((data) => cityType.includes(data.city), ); } } else { // [Jay] 매장타입이 전체가 아닌 경우 // 지역 타입이 전체인 경우 if (cityType === 'all') { selectedStoreList = storeData.filter( (data) => data.additionalInfo.storeType === storeType, ); } else { selectedStoreList = storeData.filter( (data) => data.additionalInfo.storeType === storeType && cityType.includes(data.city), ); } } storeItemsEl.children().remove(); const offlineStoreList = renderHtml($offlineStoreList, selectedStoreList); storeItemsEl.append(offlineStoreList); }; document .querySelector('offline-store-info') .addEventListener('change', changeEventListener); /** * [Aaron] 선택한 매장 지도 보기 */ function onClickShopDetailView({ target, currentTarget }) { const shopSno = $(currentTarget).data('shop-sno'); const lat = $(currentTarget).data('lat'); const lng = $(currentTarget).data('lng'); detailKakaoMap(shopSno, lat, lng); $offlineStoreInfo.find('.store__items li').removeClass('active'); $(target).closest('li').addClass('active'); } /** * [Aaron] 매장 상세 지도 생성 * @param shopSno // 매장 번호 * @param lat * @param lng */ function detailKakaoMap(shopSno, lat, lng) { const mapContainer = document.getElementById('map'); // 지도를 표시할 div // 기존에 생성된 map 제거 $('#map').children().remove(); mapOption = { center: new kakao.maps.LatLng(lat, lng), // 지도의 중심좌표 level: shopSno ? 4 : 12, // 지도의 확대 레벨 }; // 지도 생성 const map = new kakao.maps.Map(mapContainer, mapOption); const position = new kakao.maps.LatLng(lat, lng); // 마커 이미지 설정 const markerImageSrc = '/assets/images/geek/ico_location.svg'; const markerImageSize = new kakao.maps.Size(30, 30); const markerImageOption = { offset: new kakao.maps.Point(20, 40) }; const markerImage = new kakao.maps.MarkerImage( markerImageSrc, markerImageSize, markerImageOption, ); const marker = new kakao.maps.Marker({ position: position, image: markerImage, }); // 지도 중심 이동 map.setCenter(position); // 마커 표시 marker.setMap(map); if (!shopSno) return; // 현재 선택된 지점 데이터 추출 const currentData = storeData.filter((item) => { if (item.sno === shopSno) { return { shopSno: shopSno, shopName: item.shopName, address: item.address, }; } }); // [Jay] 매장 영업시간 '/' 문자로 줄바꿈 처리를 위해 배열로 변환 /* const iwContent = `
${currentData[0].address}
큰지도보기 길찾기
`; */ const iwContent = `${currentData[0].shopName}`; const iwPosition = new kakao.maps.LatLng(lat, lng); // 인포윈도우 표시 위치 var content = '
' + '' + iwContent + '' + '
'; // 인포윈도우를 생성합니다 new kakao.maps.CustomOverlay({ map: map, position: iwPosition, content: content, yAnchor: 1, }); } // 지도 확대 function onClickZoomIn() { map.setLevel(map.getLevel() - 1); } // 지도 축소 function onClickZoomOut() { map.setLevel(map.getLevel() + 1); } const offlineStoreSlideOption = { id: 'offline-store-slide', direction: 'horizontal', effect: 'slide', slidesPerView: 3, spaceBetween: 50, navigation: { nextEl: '.offline-store-image-list .swiper-button-next', prevEl: '.offline-store-image-list .swiper-button-prev', }, }; utils.initSwiper(offlineStoreSlideOption); })();