/* * © NHN Commerce Corp. All rights reserved. * NHN Corp. PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * @author Hyeyeon Park * @author Bomee Yoon * @author Eunbi Kim * @since 2021-6-23 */ $(() => { const { getUrlParam } = shopby.utils; const $searchBoxOrCategoryBoxArea = $('#searchBoxOrCategoryBoxArea'); const $categorySelector = $('#categorySelector'); const $selectedCategoryTit = $('#selectedCategoryTit'); const sectionId = getUrlParam('sectionId'); const keyword = getUrlParam('keyword'); shopby.product.list = { async initiate() { await this.productList.initiate(); $('#productsPage').removeClass('invisible').addClass('visible'); if (sectionId || keyword) return; this.category.initiate(); }, getCurrentDepthCategories() { return this.productList.getCurrentDepthCategories.call(this.productList); }, category: { data: { categories: [], selectedCategoryTit: '', selectedChildCategories: [], }, initiate() { this.setData(); this.render(); this.bindEvents(); }, setData() { this.setCategoryData(); this.setProductCount(); }, render() { const { categories, selectedCategoryTit, selectedChildCategories } = this.data; $categorySelector.render({ categories }); $selectedCategoryTit.render({ selectedCategoryTit }); $searchBoxOrCategoryBoxArea.render({ selectedChildCategories }); }, bindEvents() { $categorySelector.on('change', this.goSelectedCategory); }, goSelectedCategory({ target }) { const categoryNo = $(target).find('option:selected').data('category-no'); location.href = `/pages/product/list.html?categoryNo=${categoryNo}`; }, setCategoryData() { const name = 'categoryNo'; const searchParams = new URLSearchParams(window.location.search); if (searchParams.has(name) && Boolean(searchParams.get(name))) { const { multiLevelCategories } = shopby.cache.getCategories(); const categoryNo = Number(searchParams.get(name)); const selectData = this._getSelectData(categoryNo, multiLevelCategories, [ { children: multiLevelCategories }, ]) || { category: null, parents: [] }; const { parents, category } = selectData; this.data.categories = parents; this.data.selectedCategoryTit = category.label; this.data.selectedChildCategories = category.children; } }, setProductCount() { const { selectedChildCategories } = this.data; const currentCategories = shopby.product.list.getCurrentDepthCategories(); this.data.selectedChildCategories = selectedChildCategories.map(category => { const found = currentCategories && currentCategories.find(({ categoryNo }) => categoryNo === category.categoryNo); category.productCount = found ? found.count : 0; return category; }); }, _getSelectData(categoryNo, categoryList, parents) { const { length } = categoryList; const PARENTS_LAST_INDEX = parents.length - 1; for (let i = 0; i < length; i += 1) { const category = categoryList[i]; const { label, categoryNo: no, children, depth } = category; parents[PARENTS_LAST_INDEX].selectedLabel = label; if (categoryNo === no) { parents[PARENTS_LAST_INDEX].isParent = PARENTS_LAST_INDEX === depth - 1; return { category, parents }; } if (children && children.length > 0) { parents.push(category); const result = this._getSelectData(categoryNo, children, parents); if (result) { return result; } } if (i === length - 1) { parents.splice(PARENTS_LAST_INDEX, 1); } } }, }, //todo getUrlParam productList: { page: null, $productList: $('#productList'), data: { productInfo: null, categories: shopby.cache.getCategories(), title: null, totalCount: 0, orderDirection: 'DESC', productList: [], sorting: {}, searchWord: null, message: '진열중인 상품이 없습니다.', page: getUrlParam('page', 1), pageSize: 10, orderBy: sectionId ? getUrlParam('orderBy', 'ranking') : getUrlParam('orderBy', 'sale_cnt'), brandNo: getUrlParam('brandNo'), keyword: getUrlParam('keyword'), keywordInResult: getUrlParam('keywordInResult'), listType: getUrlParam('type', 'gallery'), categoryNo: getUrlParam('categoryNo'), }, async initiate() { this.page = new shopby.readMore(this.onClickReadMore.bind(this), '#productsMoreButton', this.data.pageSize); await this.setData(); this.render(); this.bindEvents(); }, async setData() { const { keyword, keywordInResult } = this.data; this.data.searchWord = keywordInResult ? keywordInResult : keyword; await this.setProductList(); }, render() { const { productList, searchWord, keyword, totalCount, orderBy } = this.data; this.page.render(totalCount); $('#searchResult').render({ searchWord, keyword, totalCount, sectionId }); if (this.data.keyword !== '') { this.keywordRender(); } if (sectionId) { this.sectionRender(); } this.$productList.render({ productList, message: this.data.message }); this.selectRender(orderBy); }, bindEvents() { $('#productSorting').on('change', this.onChangeProductSorting.bind(this)); $('#productList').on('click', '#wishBtn', this.onClickWishBtn.bind(this)); $('.btn_goods_search').on('click', this.onClickKeywordInResultBtn.bind(this)); $('#displayType').on('click', this.onChangeDisplayType.bind(this)); }, async setProductList() { !sectionId ? await this.fetchProductList() : await this.fetchMainSection(); this.data.productList = this.data.productList.map(product => ({ ...product, calculatedSalePrice: shopby.utils.getDisplayProductPrice(product), })); }, selectRender(orderBy) { $('#productSorting').val(orderBy).prop('selected', true); }, async onChangeDisplayType({ target }) { const displayType = target.innerText; switch (displayType) { case 'list': target.innerText = 'gallery'; $(target).css({ background: '#ffffff url("/assets/img/icon/icon_product_type_gallery2_on.png") no-repeat center', 'background-size': '16px', }); break; case 'gallery': target.innerText = 'list'; $(target).css({ background: '#ffffff url("/assets/img/icon/icon_product_type_list_on.png") no-repeat center', 'background-size': '16px', }); break; default: break; } this.page.pageNumber = 1; await this.setProductList(); this._removeProducts(); this._appendProducts(); //할인율 $(".item_money_box").each(function(){ var price = $(this).find(".item_price em").text().replace(/,/g,""); var del = $(this).find("del em").text().replace(/,/g, ""); var sale = (1-price/del)*100; var sale_per = Math.ceil(sale); $(this).find(".item_dc_per").text(sale_per + "%"); }); }, keywordRender() { this.data.message = '검색결과가 없습니다.'; $selectedCategoryTit.render({ selectedCategoryTit: '상품 검색' }); $searchBoxOrCategoryBoxArea.hide(); }, sectionRender() { $selectedCategoryTit.render({ selectedCategoryTit: this.data.title }); $searchBoxOrCategoryBoxArea.hide(); }, getCurrentDepthCategories() { const depth = Number(getUrlParam('depth')) || 1; const categoryNo = Number(getUrlParam('categoryNo')); const key = `depth${depth + 1}Categories`; return ( (this.data.productInfo[key] && this.data.productInfo[key].filter(({ parentCategoryNo }) => parentCategoryNo === categoryNo)) || null ); }, async fetchProductList() { const { direction, order } = this.mapSortingParams(this.data.orderBy); try { const queryString = { pageNumber: this.page.pageNumber, pageSize: this.page.pageSize, categoryNos: this.data.categoryNo, 'order.direction': direction, 'order.by': order, hasTotalCount: true, 'filter.keywords': this.data.keyword, 'filter.keywordInResult': this.data.keywordInResult, 'filter.saleStatus': 'ALL_CONDITIONS', 'filter.soldout': true, includeSummaryInfo: true, }; const { data } = await shopby.api.product.getProductsSearch({ queryString }); if (queryString['filter.keywords']) { shopby.setGlobalVariableBy('PRODUCT_SEARCH', data); } else { shopby.setGlobalVariableBy('PRODUCT_LIST', data); } this.data.totalCount = data.totalCount; this.data.productList = data.items; this.data.productInfo = data; } catch (e) { console.error(e); } }, async fetchMainSection() { const orders = { ranking: '', sale_cnt: 'SALE', price_asc: 'LOW_PRICE', price_dsc: 'HIGH_PRICE', review: 'REVIEW', date: 'REGISTER', }; try { const request = { pathVariable: { sectionsId: sectionId, }, queryString: { pageNumber: this.page.pageNumber, pageSize: this.page.pageSize, by: orders[this.data.orderBy], hasTotalCount: true, 'filter.keywords': this.data.keyword, 'filter.keywordInResult': this.data.keywordInResult, }, }; const { data } = await shopby.api.display.getDisplaySectionsIdsSectionId({ ...request }); shopby.setGlobalVariableBy('DISPLAY_SECTION', data); const { productTotalCount, products, label } = data; this.data.totalCount = productTotalCount; this.data.productList = products; this.data.title = label; } catch (e) { console.error(e); } }, onChangeProductSorting({ target }) { const { value } = target; return shopby.utils.sendQueryString({ orderBy: value }); }, async onClickWishBtn(event) { event.preventDefault(); const $button = $(event.currentTarget); const liked = $button.hasClass('on'); const productNo = $button.closest('li').data('product-no'); if (!shopby.logined()) { return shopby.confirmLogin(); } try { const requestBody = { productNos: [productNo] }; await shopby.api.product.postProfileLikeProducts({ requestBody }); liked ? $button.removeClass('on') : $button.addClass('on'); } catch (e) { console.error(e); } }, onClickKeywordInResultBtn() { const keywordInResult = $('input[name=keywordInResult]').val(); shopby.utils.sendQueryString({ keywordInResult }); }, mapSortingParams(paramKey) { switch (paramKey) { case 'sale_cnt': return { order: 'SALE_CNT', direction: 'DESC' }; case 'price_asc': return { order: 'DISCOUNTED_PRICE', direction: 'ASC' }; case 'price_dsc': return { order: 'DISCOUNTED_PRICE', direction: 'DESC' }; case 'review': return { order: 'REVIEW', direction: 'DESC' }; case 'recent': default: return { order: 'RECENT_PRODUCT', direction: 'DESC' }; } }, async onClickReadMore() { await this.setProductList(); this._appendProducts(); }, _removeProducts() { $('#productList').empty(); }, _appendProducts() { const { productList, totalCount } = this.data; this.page.render(totalCount); if (productList.length === 0) return; const displayType = $('#displayType').text(); const compiled = Handlebars.compile($(`#product-list-type-${displayType}`).html()); const appendHtml = $(compiled({ productList })).find('li.product_item'); $('#productList').append(appendHtml); }, }, }; shopby.start.initiate(shopby.product.list.initiate.bind(shopby.product.list)); });