Multi-Function Stainless Steel Peeler Knife

$19.99
$39.99
Save $20.00
/** * ä¼˜ęƒ ē ē»„ä»¶ęØ”åž‹ē±» * å¤„ē†ä¼˜ęƒ ē ēš„ę˜¾ē¤ŗå’Œäŗ¤äŗ’é€»č¾‘ */ class SpzCustomDiscountCodeModel extends SPZ.BaseElement { constructor(element) { super(element); // å¤åˆ¶ęŒ‰é’®å’Œå†…å®¹ēš„ē±»å this.copyBtnClass = "discount_code_btn" this.copyClass = "discount_code_value" } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { // åˆå§‹åŒ–ęœåŠ” this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); } /** * ęø²ęŸ“ä¼˜ęƒ ē ē»„ä»¶ * @param {Object} data - ęø²ęŸ“ę•°ę® */ doRender_(data) { return this.templates_ .findAndRenderTemplate(this.element, Object.assign(this.getDefaultData(), data) ) .then((el) => { this.clearDom(); this.element.appendChild(el); // ē»‘å®šå¤åˆ¶ä»£ē åŠŸčƒ½ this.copyCode(el, data); }); } /** * čŽ·å–ęø²ęŸ“ęØ”ęæ * @param {Object} data - ęø²ęŸ“ę•°ę® */ getRenderTemplate(data) { const renderData = Object.assign(this.getDefaultData(), data); return this.templates_ .findAndRenderTemplate(this.element, renderData) .then((el) => { this.clearDom(); return el; }); } /** * 清除DOM内容 */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * čŽ·å–é»˜č®¤ę•°ę® * @returns {Object} é»˜č®¤ę•°ę®åÆ¹č±” */ getDefaultData() { return { isMobile: appDiscountUtils.judgeMobile(), isRTL: appDiscountUtils.judgeRTL(), image_domain: this.win.SHOPLAZZA.image_domain, copyBtnClass: this.copyBtnClass, copyClass: this.copyClass } } /** * å¤åˆ¶ä¼˜ęƒ ē åŠŸčƒ½ * @param {Element} el - å½“å‰å…ƒē“  */ copyCode(el) { const copyBtnList = el.querySelectorAll(`.${this.copyBtnClass}`); if (copyBtnList.length > 0) { copyBtnList.forEach(item => { item.onclick = async () => { // ē”®äæčŽ·å–ę­£ē”®ēš„å…ƒē“ å’Œå†…å®¹ const codeElement = item.querySelector(`.${this.copyClass}`); if (!codeElement) return; // čŽ·å–ēŗÆę–‡ęœ¬å†…å®¹ const textToCopy = codeElement.innerText.trim(); // å°čÆ•ä½æē”ØēŽ°ä»£APIļ¼Œå¦‚ęžœå¤±č“„åˆ™ä½æē”Øå¤‡ē”Øę–¹ę”ˆ try { if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(textToCopy); } else { throw new Error('Clipboard API not available'); } // ę˜¾ē¤ŗå¤åˆ¶ęˆåŠŸęē¤ŗ this.showCopySuccessToast(textToCopy, el); } catch (err) { console.error('Modern clipboard API failed, trying fallback...', err); // ä½æē”Øå¤‡ē”Øå¤åˆ¶ę–¹ę”ˆ this.fallbackCopy(textToCopy, el); } const discountId = item.dataset["discountId"]; // 跳转决策: is_redirection + link(åÆé€‰č¦†ē›–) const setting = { is_redirection: item.dataset["redirection"] === "true", link: item.dataset["link"], }; const landingUrl = `/promotions/discount-default/${discountId}`; const finalUrl = appDiscountUtils.resolveDiscountHref(setting, landingUrl); if (finalUrl && appDiscountUtils.inProductBody(this.element)) { this.win.open(finalUrl, '_blank', 'noopener'); } } }) } } /** * 使用 execCommand ēš„å¤åˆ¶ę–¹ę”ˆ * @param {string} codeText - č¦å¤åˆ¶ēš„ę–‡ęœ¬ * @param {Element} el - å½“å‰å…ƒē“  */ fallbackCopy(codeText, el) { const textarea = this.win.document.createElement('textarea'); textarea.value = codeText; // č®¾ē½®ę ·å¼ä½æę–‡ęœ¬ę”†äøåÆč§ textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; textarea.style.top = '0'; // 添加 readonly å±žę€§é˜²ę­¢ē§»åŠØē«Æč™šę‹Ÿé”®ē›˜å¼¹å‡ŗ textarea.setAttribute('readonly', 'readonly'); this.win.document.body.appendChild(textarea); textarea.focus(); textarea.select(); try { this.win.document.execCommand('copy'); // ę˜¾ē¤ŗå¤åˆ¶ęˆåŠŸęē¤ŗ this.showCopySuccessToast(codeText, el); } catch (err) { console.error('Copy failed:', err); } this.win.document.body.removeChild(textarea); } /** * åˆ›å»ŗ Toast å…ƒē“  * @returns {Element} åˆ›å»ŗēš„ Toast å…ƒē“  */ createToastEl_() { const toast = document.createElement('ljs-toast'); toast.setAttribute('layout', 'nodisplay'); toast.setAttribute('hidden', ''); toast.setAttribute('id', 'discount-code-toast'); toast.style.zIndex = '1051'; return toast; } /** * ęŒ‚č½½ Toast å…ƒē“ åˆ° body * @returns {Element} ęŒ‚č½½ēš„ Toast å…ƒē“  */ mountToastToBody_() { const existingToast = this.win.document.getElementById('discount-code-toast'); if (existingToast) { return existingToast; } const toast = this.createToastEl_(); this.win.document.body.appendChild(toast); return toast; } /** * å¤åˆ¶ęˆåŠŸēš„ęé†’ * @param {string} codeText - č¦å¤åˆ¶ēš„ę–‡ęœ¬ * @param {Element} el - å½“å‰å…ƒē“  */ showCopySuccessToast(codeText, el) { const $toast = this.mountToastToBody_(); SPZ.whenApiDefined($toast).then(toast => { toast.showToast("Discount code copied !"); this.codeCopyInSessionStorage(codeText); }); } /** * å¤åˆ¶ä¼˜ęƒ ē ęˆåŠŸåŽč¦å­˜äø€ä»½åˆ°ęœ¬åœ°å­˜å‚Øäø­ļ¼Œč“­ē‰©č½¦ä½æē”Ø * @param {string} codeText - č¦å¤åˆ¶ēš„ę–‡ęœ¬ */ codeCopyInSessionStorage(codeText) { try { sessionStorage.setItem('other-copied-coupon', codeText); } catch (error) { console.error(error) } } } // ę³Øå†Œč‡Ŗå®šä¹‰å…ƒē“  SPZ.defineElement('spz-custom-discount-code-model', SpzCustomDiscountCodeModel);
/** * Custom discount code component that handles displaying and managing discount codes * @extends {SPZ.BaseElement} */ class SpzCustomDiscountCode extends SPZ.BaseElement { constructor(element) { super(element); // API endpoint for fetching discount codes this.getDiscountCodeApi = "\/api\/storefront\/promotion\/code\/list"; // Debounce timer for resize events this.timer = null; // Current variant ID this.variantId = "3dac6d0a-cf7d-4a92-9f55-8d56999f3a60"; // Store discount code data this.discountCodeData = {} } /** * Check if layout is supported * @param {string} layout - Layout type * @return {boolean} */ isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } /** * Initialize component after build */ buildCallback() { this.templates_ = SPZServices.templatesForDoc(); this.viewport_ = this.getViewport(); // Bind methods to maintain context this.render = this.render.bind(this); this.resize = this.resize.bind(this); this.switchVariant = this.switchVariant.bind(this); } /** * Setup component when mounted */ mountCallback() { this.getData(); // Add event listeners this.viewport_.onResize(this.resize); this.win.document.addEventListener('dj.variantChange', this.switchVariant); } /** * Cleanup when component is unmounted */ unmountCallback() { this.viewport_.removeResize(this.resize); this.win.document.removeEventListener('dj.variantChange', this.switchVariant); // ęø…é™¤å®šę—¶å™Ø if (this.timer) { clearTimeout(this.timer); this.timer = null; } } /** * Handle resize events with debouncing */ resize() { if (this.timer) { clearTimeout(this.timer) this.timer = null; } this.timer = setTimeout(() => { if (appDiscountUtils.inProductBody(this.element)) { this.render(); } else { this.renderSkeleton(); } }, 200); } /** * Handle variant changes * @param {Event} event - Variant change event */ switchVariant(event) { const variant = event.detail.selected; if (variant.product_id == 'd721dc45-3524-43b9-bafa-08194a11bf2e' && variant.id != this.variantId) { this.variantId = variant.id; this.getData(); } } /** * Fetch discount code data from API */ getData() { if (appDiscountUtils.inProductBody(this.element)) { const reqBody = { product_id: "d721dc45-3524-43b9-bafa-08194a11bf2e", variant_id: this.variantId, product_type: "default", } if (!reqBody.product_id || !reqBody.variant_id) return; this.discountCodeData = {}; this.win.fetch(this.getDiscountCodeApi, { method: "POST", body: JSON.stringify(reqBody), headers: { "Content-Type": "application/json" } }).then(async (response) => { if (response.ok) { let data = await response.json(); if (data.list && data.list.length > 0) { data.list[0].product_setting.template_config = JSON.parse(data.list[0].product_setting.template_config); // Format timestamps to local timezone const zone = this.win.SHOPLAZZA.shop.time_zone; data.list = data.list.map(item => { if(+item.ends_at !== -1) { item.ends_at = appDiscountUtils.convertTimestampToFormat(+item.ends_at, zone); } item.starts_at = appDiscountUtils.convertTimestampToFormat(+item.starts_at, zone); return item; }); } this.discountCodeData = data; this.render(); } else { this.clearDom(); } }).catch(err => { console.error("discount_code", err) this.clearDom(); }); } else { this.renderSkeleton(); } } /** * Clear component DOM except template */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * Render discount codes with formatted dates */ render() { // Render using discount code model SPZ.whenApiDefined(document.querySelector('#spz_custom_discount_code_model')).then(renderApi => { renderApi.doRender_({ discountCodeData: this.discountCodeData }) }).catch(err => { this.clearDom(); }) } renderSkeleton() { // Render template for non-product pages this.templates_ .findAndRenderTemplate(this.element, { isMobile: appDiscountUtils.judgeMobile() }) .then((el) => { this.clearDom(); this.element.appendChild(el); }) .catch(err => { this.clearDom(); }); } } // Register custom element SPZ.defineElement('spz-custom-discount-code', SpzCustomDiscountCode);
BUY MORE SAVE MOREšŸ”„
Quantity
Share the love
Description

Description


Product description

šŸ„’ć€Easy to Clean & Portable怑This Multifunctional Vegetable Peeler has a simple structure for easy rinsing. It can be quickly cleaned with water after use, features a compact size to save storage space, fits in drawers and is suitable for home kitchens, camping and picnics.

šŸ„•ć€Comfortable Grip怑This Multifunctional Vegetable Peeler comes with an ergonomic non-slip handle design. It offers a stable and firm grip, reduces hand fatigue during long-time use, provides precise control and works well for detailed cutting and daily peeling tasks.

šŸ‰ć€Wide Cutting Surface怑This Multifunctional Vegetable Peeler has an arc-shaped wide cutting opening that covers a larger food area at one time. It quickly processes thick-skinned ingredients, cuts evenly in thickness, reduces food waste and makes batch food preparation more efficient.Ā 

šŸ„”ć€2-in-1 Multifunctional Design怑This Multifunctional Vegetable Peeler integrates shredding, peeling, decorative cutting and bottle opening functions. It handles daily food prep, dish plating and beverage opening with ease, reduces kitchen clutter and is convenient for home use, gatherings and outdoor activities.

šŸŽć€Sharp Blade怑This Multifunctional Vegetable Peeler features precision stainless steel blades for smooth and clean cutting. It quickly handles green onions, vegetables and fruits, easily shreds, peels and creates decorative cuts, greatly improves food preparation efficiency and adapts to various food processing needs.