(function () { 'use strict'; const WPDATA = typeof vertuCatalogAjax !== 'undefined' ? vertuCatalogAjax : {}; const config = { ajaxUrl: WPDATA.ajax_url, nonce: WPDATA.nonce, pageSize: 12 }; const state = { allCategories: [], currentMainCategory: null, currentSubCategory: null, currentSelectedCategoryId: null, currentSortBy: 'default', currentPage: 1, }; const DOM = {}; //【恢复】这个 map 作为 "Learn More" 链接的首选来源 const landingPageMap = { "Quantum Flip": "https://vertu.com/quantum/", "Metavertu Curve": "https://vertu.com/metavertu-curve/", "Metavertu 2 Max": "https://vertu.com/metamax/", "Grand Watch": "https://vertu.com/grandwatch/", "Aura Ring": "https://vertu.com/aura-ring/", "Signature S": "https://vertu.com/signature-s/", "Ironflip": "https://vertu.com/page-ironflip/", "OWS Earbuds": "https://vertu.com/ows-earbuds/", "AI Diamond Ring": "https://vertu.com/smartring/" }; //【恢复】这个函数用于从 map 中查找链接 function getLandingPageUrlByName(productName) { const name = productName.toLowerCase(); let bestMatch = null; let longestKey = 0; for (const key in landingPageMap) { const lowerKey = key.toLowerCase(); if (name.includes(lowerKey)) { if (lowerKey.length > longestKey) { bestMatch = landingPageMap[key]; longestKey = lowerKey.length; } } } return bestMatch; } function initDOMCache() { DOM.catalogWrapper = document.querySelector('.vertu-catalog-wrapper'); if (!DOM.catalogWrapper) { return false; } const requiredIds = ['initial-loading', 'error-state', 'product-list', 'banner-categories', 'category-dropdown', 'dropdown-menu', 'sort-dropdown-btn', 'sort-dropdown-menu', 'discover-prev-btn', 'discover-next-btn']; for (const id of requiredIds) { DOM[id.replace(/-/g, '_')] = document.getElementById(id); if (!DOM[id.replace(/-/g, '_')]) { console.warn(`#${id} not found.`); return false; } } DOM.banner_title = DOM.catalogWrapper.querySelector('.banner-title'); DOM.banner_desc = DOM.catalogWrapper.querySelector('.banner-desc'); return true; } async function fetchData(action, data = {}) { try { const formData = new FormData(); formData.append('action', action); formData.append('nonce', config.nonce); for (const key in data) { formData.append(key, data[key]); } const response = await fetch(config.ajaxUrl, { method: 'POST', body: formData }); if (!response.ok) throw new Error(`Network error: ${response.status}`); const result = await response.json(); if (!result.success) throw new Error(result.data || 'AJAX request failed.'); return result.data; } catch (error) { console.error(`Failed to fetch ${action}:`, error); loadingManager.showError(error.message); return null; } } //【修改】实现混合式 "Learn More" 链接逻辑 function renderProductCard(product) { let learnMoreUrl = null; // 1. 优先从 JS map 中查找 const urlFromMap = getLandingPageUrlByName(product.name); if (urlFromMap) { learnMoreUrl = urlFromMap; } // 2. 如果 map 中没有,则使用从 WP 后端传来的链接作为后备 else if (product.learn_more_url) { learnMoreUrl = product.learn_more_url; } let learnMoreButtonHtml = ''; if (learnMoreUrl) { learnMoreButtonHtml = `Learn more`; } const imageHtml = product.image_html || ``; return `
${product.on_sale ? '
On Sale
' : ''}
${imageHtml}

${product.name}

${product.price_html}
${product.stock_status !== 'outofstock' ? `Buy now` : ''} ${learnMoreButtonHtml}
`; } function renderProductsPaged(newProducts, reset = false) { if (reset) { DOM.product_list.innerHTML = newProducts.map(renderProductCard).join(''); } else { DOM.product_list.insertAdjacentHTML('beforeend', newProducts.map(renderProductCard).join('')); } let loadMoreBtn = DOM.catalogWrapper.querySelector('.load-more-btn'); if (loadMoreBtn) loadMoreBtn.remove(); if (newProducts.length === config.pageSize) { loadMoreBtn = document.createElement('button'); loadMoreBtn.className = 'load-more-btn'; loadMoreBtn.textContent = 'Load more'; loadMoreBtn.onclick = async (e) => { const btn = e.target; btn.textContent = 'Loading...'; btn.disabled = true; state.currentPage++; await updateProductsDisplay(false); }; DOM.product_list.parentNode.appendChild(loadMoreBtn); } } async function updateProductsDisplay(reset = true) { if (reset) { state.currentPage = 1; loadingManager.showLoading(); } const products = await fetchData('vertu_get_products', { category_id: state.currentSelectedCategoryId, sort_by: state.currentSortBy, page: state.currentPage, posts_per_page: config.pageSize }); if (products) { renderProductsPaged(products, reset); } if (reset) { loadingManager.hideLoading(); } } function renderSubCategories() { const parentId = state.currentMainCategory ? state.currentMainCategory.id : 0; let subCats = state.allCategories.filter(cat => cat.parent === parentId); // 添加调试信息 console.log('Current main category:', state.currentMainCategory?.name, 'ID:', parentId); console.log('Sub categories found:', subCats.length); subCats.forEach(cat => console.log('-', cat.name, 'term_order:', cat.term_order)); // 使用WordPress的term_order排序,如果都为0则按名称排序 subCats.sort((a, b) => { const orderA = parseInt(a.term_order) || 0; const orderB = parseInt(b.term_order) || 0; // 如果term_order都为0,按名称排序 if (orderA == 0 && orderB == 0) { return a.name.localeCompare(b.name); } // 否则按term_order排序 return orderA - orderB; }); // 添加排序后的调试信息 console.log('Sorted sub categories:'); subCats.forEach((cat, index) => console.log(`${index + 1}. ${cat.name} (term_order: ${cat.term_order})`)); if (DOM.banner_categories) { const imagePlaceholder = ``; DOM.banner_categories.innerHTML = subCats.map(cat => { const isActive = state.currentSubCategory && state.currentSubCategory.id === cat.id; return ``; }).join(''); } } function renderCategoryDropdown() { if (!state.currentMainCategory) return; const parentId = state.currentMainCategory.id; let subCats = state.allCategories.filter(cat => cat.parent === parentId); // 使用WordPress的term_order排序,如果都为0则按名称排序 subCats.sort((a, b) => { const orderA = parseInt(a.term_order) || 0; const orderB = parseInt(b.term_order) || 0; // 如果term_order都为0,按名称排序 if (orderA == 0 && orderB == 0) { return a.name.localeCompare(b.name); } // 否则按term_order排序 return orderA - orderB; }); let html = ``; html += subCats.map(cat => { const isSelected = state.currentSubCategory && state.currentSubCategory.id === cat.id; return ``; }).join(''); if (DOM.dropdown_menu) DOM.dropdown_menu.innerHTML = html; } function updateActiveCategory(catId) { if(state.currentSelectedCategoryId === catId) return; if(catId === 0) { state.currentMainCategory = null; state.currentSubCategory = null; state.currentSelectedCategoryId = null; } else { state.currentSelectedCategoryId = catId; const selectedCat = state.allCategories.find(c => c.id === catId); if (selectedCat) { if (selectedCat.parent === 0) { if (state.currentMainCategory?.id !== selectedCat.id) { state.currentMainCategory = selectedCat; state.currentSubCategory = null; renderSubCategories(); renderCategoryDropdown(); } } else { state.currentSubCategory = selectedCat; const parentCat = state.allCategories.find(c => c.id === selectedCat.parent); if (parentCat && state.currentMainCategory?.id !== parentCat.id) { state.currentMainCategory = parentCat; renderSubCategories(); renderCategoryDropdown(); } } } } document.querySelectorAll('.banner-category-card.active').forEach(c => c.classList.remove('active')); const activeCard = DOM.banner_categories.querySelector(`[data-cat-id="${catId}"]`); if (activeCard) activeCard.classList.add('active'); updateDropdownBtnText(); updateProductsDisplay(true); } function updateDropdownBtnText() { const allSpan = DOM.category_dropdown.querySelector('.dropdown-all'); const maincatSpan = DOM.category_dropdown.querySelector('.dropdown-maincat'); if (!allSpan || !maincatSpan) return; if (state.currentSubCategory) { allSpan.textContent = ''; maincatSpan.textContent = state.currentSubCategory.name; } else if (state.currentMainCategory) { allSpan.textContent = 'All'; maincatSpan.textContent = ` ${state.currentMainCategory.name}`; } else { allSpan.textContent = 'All'; maincatSpan.textContent = ' Categories'; } } async function startApp() { if (!initDOMCache()) { loadingManager.showError('Failed to initialize page elements.'); return; } loadingManager.showInitialLoading(); const categories = await fetchData('vertu_get_categories'); if(!categories) return; state.allCategories = categories.filter(c => c.name !== 'Payment Link' && typeof c.parent !== 'undefined'); const initialCategorySlug = DOM.catalogWrapper.dataset.initialCategory; let mainCategories = state.allCategories.filter(cat => cat.parent === 0); // 使用与PHP后端相同的排序逻辑 mainCategories.sort((a, b) => { // 优先使用term_order,如果都为0则使用menu_order if ((a.term_order || 0) != 0 || (b.term_order || 0) != 0) { return (a.term_order || 0) - (b.term_order || 0); } // 如果term_order都为0,使用menu_order if ((a.menu_order || 0) != 0 || (b.menu_order || 0) != 0) { return (a.menu_order || 0) - (b.menu_order || 0); } // 最后按名称排序 return a.name.localeCompare(b.name); }); let initialCategory = null; if(initialCategorySlug) { initialCategory = state.allCategories.find(cat => cat.slug.toLowerCase() === initialCategorySlug.toLowerCase() && cat.parent === 0); } state.currentMainCategory = initialCategory || mainCategories[0] || null; if (state.currentMainCategory) { state.currentSelectedCategoryId = state.currentMainCategory.id; DOM.banner_title.textContent = state.currentMainCategory.name; DOM.banner_desc.innerHTML = state.currentMainCategory.description || ''; renderSubCategories(); renderCategoryDropdown(); updateDropdownBtnText(); await updateProductsDisplay(true); } else { loadingManager.showError('No product categories found.'); } dropdownManager.init(); initEventListeners(); initScrollButtons(); loadingManager.hideInitialLoading(); } function initializeCatalog() { const catalogWrapper = document.querySelector('.vertu-catalog-wrapper'); if (!catalogWrapper) { let attempts = 0; const interval = setInterval(function() { const wrapper = document.querySelector('.vertu-catalog-wrapper'); if (wrapper) { clearInterval(interval); startApp(); } attempts++; if (attempts > 50) { clearInterval(interval); console.error('Catalog wrapper did not appear after 5 seconds. Aborting.'); const errorDiv = document.getElementById('error-state'); if (errorDiv) { const errorText = errorDiv.querySelector('.error-state-text'); if (errorText) errorText.textContent = 'Failed to load catalog content.'; errorDiv.style.display = 'flex'; } } }, 100); return; } startApp(); } const dropdownManager = { init() { this.menus = { category: DOM.dropdown_menu, sort: DOM.sort_dropdown_menu }; this.buttons = { category: DOM.category_dropdown, sort: DOM.sort_dropdown_btn }; this.currentOpenMenu = null; this.bindEvents(); }, bindEvents() { Object.entries(this.buttons).forEach(([type, button]) => { if (button) button.addEventListener('click', (e) => { e.stopPropagation(); this.toggleMenu(type); }); }); document.addEventListener('click', () => this.closeAllMenus()); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') this.closeAllMenus(); }); }, toggleMenu(type) { this.currentOpenMenu === type ? this.closeAllMenus() : this.openMenu(type); }, openMenu(type) { this.closeAllMenus(); if(this.menus[type]) this.menus[type].style.display = 'block'; if(this.buttons[type]) this.buttons[type].classList.add('active'); this.currentOpenMenu = type; }, closeAllMenus() { if (!this.currentOpenMenu) return; if(this.menus[this.currentOpenMenu]) this.menus[this.currentOpenMenu].style.display = 'none'; if(this.buttons[this.currentOpenMenu]) this.buttons[this.currentOpenMenu].classList.remove('active'); this.currentOpenMenu = null; } }; function initEventListeners() { if (DOM.banner_categories) DOM.banner_categories.addEventListener('click', e => { const card = e.target.closest('.banner-category-card'); if (card && card.dataset.catId) updateActiveCategory(parseInt(card.dataset.catId, 10)); }); if (DOM.dropdown_menu) DOM.dropdown_menu.addEventListener('click', e => { const item = e.target.closest('.dropdown-item'); if (item && item.dataset.catId) updateActiveCategory(parseInt(item.dataset.catId, 10)); }); if (DOM.sort_dropdown_menu) DOM.sort_dropdown_menu.addEventListener('click', e => { const item = e.target.closest('.sort-dropdown-item'); if (item && item.dataset.sort) { state.currentSortBy = item.dataset.sort; DOM.sort_dropdown_menu.querySelectorAll('.sort-dropdown-item').forEach(i => i.classList.remove('selected')); item.classList.add('selected'); updateProductsDisplay(true); dropdownManager.closeAllMenus(); } }); } function initScrollButtons() { if (DOM.discover_prev_btn && DOM.discover_next_btn && DOM.banner_categories) { DOM.discover_prev_btn.addEventListener('click', () => { DOM.banner_categories.scrollBy({ left: -300, behavior: 'smooth' }); }); DOM.discover_next_btn.addEventListener('click', () => { DOM.banner_categories.scrollBy({ left: 300, behavior: 'smooth' }); }); } } const loadingManager = { getInitialLoadingEl() { return document.getElementById('initial-loading'); }, getErrorStateEl() { return document.getElementById('error-state'); }, showInitialLoading() { const el = this.getInitialLoadingEl(); if (el) el.style.display = 'flex'; }, hideInitialLoading() { const el = this.getInitialLoadingEl(); if (el) el.style.display = 'none'; }, showLoading() { renderSkeletonCards(config.pageSize); }, hideLoading() { /* This function is now intentionally left blank as renderProductsPaged handles content replacement */ }, showError(message) { this.hideInitialLoading(); if (DOM.product_list) DOM.product_list.innerHTML = ''; const el = this.getErrorStateEl(); if (el) { const textEl = el.querySelector('.error-state-text'); if (textEl) textEl.textContent = message; el.style.display = 'flex'; } else { alert(`Error: ${message}`); } } }; function renderSkeletonCards(count) { let html = ''; for (let i = 0; i < count; i++) { html += `
`; } if (DOM.product_list) DOM.product_list.innerHTML = html; } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeCatalog); } else { initializeCatalog(); } })(); أحدث منتجات Vertu والأخبار والابتكارات AI - الموقع الرسمي لـ VERTU®

الموقع الرسمي لـVERTU®

Shopping Cart

VERTU Exclusive Benefits