Brown Pleated Mesh Bodycon Dress

$39.99
/** * 优惠码组件模型类 * 处理优惠码的显示和交互逻辑 */ 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 = "b4c0fe28-fe96-488a-b4d4-81f43f0e0411"; // 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 == 'c6573e98-a6da-4993-80ed-271287328433' && 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: "c6573e98-a6da-4993-80ed-271287328433", 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);
Color:  Brown
Size:  2XL
Quantity

Description

To initiate a return/exchange, please email us at support@ashoul.com

  • Order number
  • Name of the item(s) you wish to return/exchange
  • Reasons for the return/exchange
  • Photos of the item(s) you wish to return/exchange, clearly showing the item(s) and the attached tags

Order Cancellation:

If your order has not yet shipped, you may () to request a cancellation and refund. We will process your request within 24 hours.

Acceptable Return Conditions:

  1. Please ensure the product and packaging are intact, with no visible signs of use, and do not affect resale. Otherwise, we may refuse the refund.
  2. Please contact us within 30 days of receiving your order to request after-sales service. Our after-sales protection period is within 30 calendar days of receiving the goods. 

Return Process:

  1. Do not return the product directly to the shipping address! All return and refund requests must first be submitted to us. You can find all our contact information on the " page.
  2. We will send you a return link. Please return the product to the warehouse address specified in the return link. The warehouse location may vary based on your location. You will be responsible for the shipping costs.
  3. Once the return package is sent, it typically takes 7-30 days to reach our warehouse, depending on the distance between the warehouse and your location.

Return Shipping Fees:

  • If the return is caused by the consumer, consumer should be responsible for the shipping fee. The specific fee should be based on the express company you choose.
  • If due to our reasons, the goods received are damaged or not correct, and the consumer is not required to bear the shipping fee for this reason.

Refunds:

After we receive your return package and confirm that the product meets the return requirements, we will process your refund immediately. Usually, you will receive the refund within 3-7 days. 

* Please allow an extra 3-5 days to process the returned items due to high processing volume in the warehouse.

  1. If you paid by credit or debit card, refunds will be sent to the card-issuing bank within 5 business days of receipt of the returned item or cancellation request. Please contact the card-issuing bank with questions about when the credit will be posted to your account.
  2. If you paid by PayPal, Klarna or other online payment providers, refunds will be sent to the PayPal, Klarna or the online payment method you chose within 5 business days of receipt of the returned item or cancellation request. Please contact the online payment providers with questions about when the refund will be posted to your account.

Except for the important interpretation, we will make a Refund, Resend, or Accept the Return for any of the following cases:

1. Orders Delayed.

Orders are lack tracking information, in transit, pending, and expired after 60 days from the date that the order departed from our warehouse. The following countries and shipping methods may be different:

  • For orders shipped to the USA, it is 38 days from the date that the order departed from our warehouse.
  • For Brazil, it is 110 days from the date that the order departed from our warehouse due to the strict customs clearance in Brazil.
  • For some special shipping methods, we cannot deal with your after-sales issues. (See the following important interpretation)
Notes:

Sometimes, the order arrives at the nearest post office to you and makes it pending because of insufficient address, package unclaimed, no such number, etc. It will be much more convenient for you to contact the local post office or go to the post office for delivery.

2. Order not received.

We will not deal with the refund or resend if the tracking information shows the order has been delivered.

  • If you do not receive the package, a non-delivery certification issued by the local post office with an official seal is necessary.
  • Tracking Information Alert. The tracking information shows Alert, the reasons listed below:
    • Incorrect/insufficient Address.
    • No Such Number.
    • Recipient unknown.
    • Refused.
    • Do not pick up in time.
    • No safe delivery location.
    • Uncleared customs.
    • Others.
Notes:
  • The local distributor will deliver 1-3 times according to the actual situation. If it is still unclaimed during the delivery period, it will be returned to the local post office for storage in 3-7 days. Meanwhile, you need to pick up the package by yourself. Otherwise, the product will be returned to the sender, our logistics company.
  • We cannot offer a refund or resend if you don’t process the undelivered order or the package is destroyed by the logistics company.
  • If orders that have not been signed for are not handled in time or have been destroyed by the shipping company, ASHOUL can not refund or resend the item.
3. Products Damaged.

We provide full refund or replacement if packages arrived are badly damaged.

We provide partial refund/replacement if packages arrive are partially damaged (except thread, slightly wrinkled, small scratches, etc.).

Notes:
  • For fragile products, a refund is highly recommended.
  • For damaged packing boxes, We cannot offer any refunds or other after-sale services due to the long-distance international delivery.
  • For ordinary products, you shall apply for after-sales service within 30 days after the package is delivered.
  • For electronic products, you shall apply for after-sales service within 30 days after the package is delivered.
4. Incorrect or Missing Products.

We have a strict quality control process before products are dispatched. We will deal with incorrect or missing products as follows:

  • For incorrect products, we offer a full refund or replacement.
  • For products with the wrong color, size which doesn’t affect product function, etc., we offer a partial refund.
  • For parts missing which doesn’t affect product function, we may refund partial or resend the missing part; for parts missing which affect product function, we resend the product only.
  • For accessories, we will resend the accessories.
5. Lost Items
We are not responsible for customs fees, taxes. And we are NOT liable for any misplaced, lost or stolen item/s.
We also NOT responsible for any incorrect shipping information you provide.

Notes:

  1. Missing Parts:

    • If parts are missing but do not affect the product’s functionality, we may offer a partial refund or resend the missing part.
    • If parts are missing and affect the product’s functionality, we will only resend the complete product.
  2. Shipping and Refunds:
    For items that have already been shipped, customers must receive the package before initiating any refund request.

  3. Incorrect Address Information:
    If the customer provides incorrect address details, such as an unreachable phone number, missing house number, incomplete address, or any other address errors, we do not accept unconditional refunds. Each case will be evaluated individually.

  4. Intimate Items:
    Intimate products such as lingerie, swimwear, and undergarments are non-returnable due to hygiene reasons. If there are size or quality issues, we offer exchanges or partial refunds, but we do not accept returns for refunds.

  5. Orders Over $300:
    For orders exceeding $300, a 20% processing fee will be charged for any return or refund request to cover the administrative costs associated with the refund process.

We always try to offer the best service. If you have any other questions, please feel free to .

Brown Pleated Mesh Bodycon Dress Product DetailsDesign: PleatedStyle: SexyThickness: RegularMaterial: PolyesterOccasion: DailySize & FitDress Length: Maxi dressElasticity: Slightly ElasticFit Type: Regular FitSize:Note:1. Choose the larger size if your size is between two sizes. Please allow 2-3cm differences due to manual measurement.2. Please check the size chart carefully before you buy the item, if you don't know how to choose a size, please contact our customer service.3. As you know, the different computers display colors differently, the color of the actual item may vary slightly from the following images.Packing list:Dress*1 59.99