echarts-all.js:1 Dom’s width & height should be ready before init.

本文介绍了ECharts在页面加载时出现的两个常见错误:容器尺寸未设置导致的图表无法显示及favicon.ico图标文件未找到的问题。通过为图表容器设置明确的宽高,并确保图标文件路径正确或存在,可以有效解决这些问题。

1、错误描述

echarts-all.js:1 Dom’s width & height should be ready before init.i._init @ echarts-all.js:1
http://127.0.0.1:8020/favicon.ico Failed to load resource: the server responded with a status of 404 (Not Found)


2、错误原因

(1)echarts容器在初始化需要设置高度和宽度,而实例中没有

<body>
	   <div id="column"></div>
	</body>


(2)找不到favicon.ico


3、解决办法

(1)设置div容器的高度和宽度

<div id="column" style="width: 1350px; height: 600px;"></div>

(2)修改favicon.ico 路径

on functions.php, it says Your PHP code changes were not applied due to an error on line 82 of file wp-content/themes/woodmart-child/functions.php. Please fix and try saving again. Uncaught TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given in wp-content/themes/woodmart-child/functions.php:82 Stack trace: #0 wp-content/themes/woodmart-child/functions.php(82): method_exists() #1 wp-includes/class-wp-hook.php(324): {closure}() #2 wp-includes/class-wp-hook.php(348): WP_Hook-&gt;apply_filters() #3 wp-includes/plugin.php(517): WP_Hook-&gt;do_action() #4 wp-settings.php(749): do_action() #5 wp-config.php(105): require_once(&lsquo;/home/u18285596&hellip;&rsquo;) #6 wp-load.php(50): require_once(&lsquo;/home/u18285596&hellip;&rsquo;) #7 wp-admin/admin.php(35): require_once(&lsquo;/home/u18285596&hellip;&rsquo;) #8 wp-admin/theme-editor.php(10): require_once(&lsquo;/home/u18285596&hellip;&rsquo;) #9 {main} thrown cart.php &lt;?php /** * Custom Cart Page for WooCommerce with Selective Checkout */ if (!defined(&#39;ABSPATH&#39;)) { exit; } do_action(&#39;woocommerce_before_cart&#39;); // Provide context for JS (no layout change) $pc_cart_is_empty = WC()-&gt;cart-&gt;is_empty(); function pc_uid_for_view() { if (is_user_logged_in()) return &#39;user_&#39; . get_current_user_id(); if (empty($_COOKIE[&#39;pc_cart_uid&#39;])) { $token = wp_generate_uuid4(); setcookie(&#39;pc_cart_uid&#39;, $token, time() + YEAR_IN_SECONDS, COOKIEPATH ?: &#39;/&#39;, &#39;&#39;, is_ssl(), false); $_COOKIE[&#39;pc_cart_uid&#39;] = $token; } return &#39;guest_&#39; . sanitize_text_field(wp_unslash($_COOKIE[&#39;pc_cart_uid&#39;])); } $pc_uid = pc_uid_for_view(); // 已修正:仅在令牌存在时恢复购物车 if (method_exists(WC()-&gt;session, &#39;get&#39;)) { $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if ($token &amp;&amp; !WC()-&gt;cart-&gt;is_empty()) { $payload = get_transient(pc_transient_key($token)); if (!empty($payload[&#39;snapshot&#39;])) { pc_restore_cart_from_items($payload[&#39;snapshot&#39;]); WC()-&gt;cart-&gt;calculate_totals(); } } } ?&gt; &lt;div class=&quot;cart-page-section container&quot; style=&quot;max-width: 1200px; margin: 0 auto;&quot;&gt; &lt;form class=&quot;woocommerce-cart-form&quot; action=&quot;&lt;?php echo esc_url( wc_get_cart_url() ); ?&gt;&quot; method=&quot;post&quot;&gt; &lt;?php do_action(&#39;woocommerce_before_cart_table&#39;); ?&gt; &lt;?php wp_nonce_field(&#39;woocommerce-cart&#39;, &#39;woocommerce-cart-nonce&#39;); ?&gt; &lt;table class=&quot;shop_table shop_table_responsive cart woocommerce-cart-form__contents&quot;&gt; &lt;thead&gt; &lt;tr&gt; &lt;th class=&quot;product-select&quot; style=&quot;width: 8%;&quot;&gt; &lt;input type=&quot;checkbox&quot; id=&quot;select-all-items&quot; /&gt; &lt;label for=&quot;select-all-items&quot; style=&quot;display: inline-block; margin-left: 5px; cursor: pointer;&quot;&gt;全选&lt;/label&gt; &lt;/th&gt; &lt;th class=&quot;product-info&quot;&gt;&lt;?php esc_html_e(&#39;Product&#39;, &#39;woocommerce&#39;); ?&gt;&lt;/th&gt; &lt;th class=&quot;product-price&quot;&gt;&lt;?php esc_html_e(&#39;Price&#39;, &#39;woocommerce&#39;); ?&gt;&lt;/th&gt; &lt;th class=&quot;product-quantity&quot;&gt;&lt;?php esc_html_e(&#39;Quantity&#39;, &#39;woocommerce&#39;); ?&gt;&lt;/th&gt; &lt;th class=&quot;product-subtotal&quot;&gt;&lt;?php esc_html_e(&#39;Subtotal&#39;, &#39;woocommerce&#39;); ?&gt;&lt;/th&gt; &lt;th class=&quot;product-remove&quot;&gt;&lt;?php esc_html_e(&#39;操作&#39;, &#39;woocommerce&#39;); ?&gt;&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;?php do_action(&#39;woocommerce_before_cart_contents&#39;); ?&gt; &lt;?php foreach ( WC()-&gt;cart-&gt;get_cart() as $cart_item_key =&gt; $cart_item ) : ?&gt; &lt;?php $_product = apply_filters(&#39;woocommerce_cart_item_product&#39;, $cart_item[&#39;data&#39;], $cart_item, $cart_item_key); $product_id = apply_filters(&#39;woocommerce_cart_item_product_id&#39;, $cart_item[&#39;product_id&#39;], $cart_item, $cart_item_key); if ( $_product &amp;&amp; $_product-&gt;exists() &amp;&amp; $cart_item[&#39;quantity&#39;] &gt; 0 &amp;&amp; apply_filters(&#39;woocommerce_cart_item_visible&#39;, true, $cart_item, $cart_item_key) ) : $product_permalink = apply_filters(&#39;woocommerce_cart_item_permalink&#39;, $_product-&gt;is_visible() ? $_product-&gt;get_permalink($cart_item) : &#39;&#39;, $cart_item, $cart_item_key); $line_total_value = (float) ($cart_item[&#39;line_total&#39;] + $cart_item[&#39;line_tax&#39;]); $variation_id = isset($cart_item[&#39;variation_id&#39;]) ? (int)$cart_item[&#39;variation_id&#39;] : 0; $variation_data = isset($cart_item[&#39;variation&#39;]) ? $cart_item[&#39;variation&#39;] : array(); $variation_json = wp_json_encode($variation_data); ?&gt; &lt;tr class=&quot;woocommerce-cart-form__cart-item &lt;?php echo esc_attr( apply_filters(&#39;woocommerce_cart_item_class&#39;, &#39;cart_item&#39;, $cart_item, $cart_item_key) ); ?&gt;&quot; data-cart_item_key=&quot;&lt;?php echo esc_attr($cart_item_key); ?&gt;&quot; data-product_id=&quot;&lt;?php echo esc_attr($product_id); ?&gt;&quot; data-variation_id=&quot;&lt;?php echo esc_attr($variation_id); ?&gt;&quot; data-variation=&quot;&lt;?php echo esc_attr($variation_json); ?&gt;&quot;&gt; &lt;!-- Checkbox Column --&gt; &lt;td class=&quot;product-select&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;Select&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;input type=&quot;checkbox&quot; class=&quot;item-checkbox&quot; name=&quot;selected_items[]&quot; value=&quot;&lt;?php echo esc_attr($cart_item_key); ?&gt;&quot; data-price=&quot;&lt;?php echo esc_attr($line_total_value); ?&gt;&quot; /&gt; &lt;/td&gt; &lt;!-- Product Info Column --&gt; &lt;td class=&quot;product-info&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;Product&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;div class=&quot;product-image&quot;&gt; &lt;?php $thumbnail = apply_filters(&#39;woocommerce_cart_item_thumbnail&#39;, $_product-&gt;get_image(), $cart_item, $cart_item_key); if ( ! $product_permalink ) : echo $thumbnail; // PHPCS: XSS ok. else : printf(&#39;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&#39;, esc_url($product_permalink), $thumbnail); // PHPCS: XSS ok. endif; ?&gt; &lt;/div&gt; &lt;div class=&quot;product-name&quot;&gt; &lt;?php if ( ! $product_permalink ) : echo wp_kses_post( apply_filters(&#39;woocommerce_cart_item_name&#39;, $_product-&gt;get_name(), $cart_item, $cart_item_key) . &#39;&nbsp;&#39; ); else : echo wp_kses_post( apply_filters(&#39;woocommerce_cart_item_name&#39;, sprintf(&#39;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&#39;, esc_url($product_permalink), $_product-&gt;get_name()), $cart_item, $cart_item_key) ); endif; do_action(&#39;woocommerce_after_cart_item_name&#39;, $cart_item, $cart_item_key); echo wc_get_formatted_cart_item_data($cart_item); // PHPCS: XSS ok. ?&gt; &lt;/div&gt; &lt;/td&gt; &lt;!-- Price Column --&gt; &lt;td class=&quot;product-price&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;Price&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;?php echo apply_filters(&#39;woocommerce_cart_item_price&#39;, WC()-&gt;cart-&gt;get_product_price($_product), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?&gt; &lt;/td&gt; &lt;!-- Quantity Column --&gt; &lt;td class=&quot;product-quantity&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;Quantity&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;?php if ( $_product-&gt;is_sold_individually() ) : $product_quantity = sprintf(&#39;1 &lt;input type=&quot;hidden&quot; name=&quot;cart[%s][qty]&quot; value=&quot;1&quot; /&gt;&#39;, $cart_item_key); else : $product_quantity = woocommerce_quantity_input( array( &#39;input_name&#39; =&gt; &quot;cart[{$cart_item_key}][qty]&quot;, &#39;input_value&#39; =&gt; $cart_item[&#39;quantity&#39;], &#39;max_value&#39; =&gt; $_product-&gt;get_max_purchase_quantity(), &#39;min_value&#39; =&gt; &#39;0&#39;, &#39;product_name&#39; =&gt; $_product-&gt;get_name(), ), $_product, false ); endif; echo apply_filters(&#39;woocommerce_cart_item_quantity&#39;, $product_quantity, $cart_item_key, $cart_item); // PHPCS: XSS ok. ?&gt; &lt;small class=&quot;qty-status&quot; style=&quot;display:none;margin-left:8px;color:#666;&quot;&gt;保存中&hellip;&lt;/small&gt; &lt;/td&gt; &lt;!-- Subtotal Column --&gt; &lt;td class=&quot;product-subtotal&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;Subtotal&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;?php echo apply_filters(&#39;woocommerce_cart_item_subtotal&#39;, WC()-&gt;cart-&gt;get_product_subtotal($_product, $cart_item[&#39;quantity&#39;]), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?&gt; &lt;/td&gt; &lt;!-- Remove Item Column --&gt; &lt;td class=&quot;product-remove&quot; data-title=&quot;&lt;?php esc_attr_e(&#39;操作&#39;, &#39;woocommerce&#39;); ?&gt;&quot;&gt; &lt;?php echo apply_filters(&#39;woocommerce_cart_item_remove_link&#39;, sprintf( &#39;&lt;a href=&quot;%s&quot; class=&quot;remove&quot; aria-label=&quot;%s&quot; data-product_id=&quot;%s&quot; data-product_sku=&quot;%s&quot;&gt;&times;&lt;/a&gt;&#39;, esc_url( wc_get_cart_remove_url($cart_item_key) ), esc_attr__(&#39;Remove this item&#39;, &#39;woocommerce&#39;), esc_attr($product_id), esc_attr($_product-&gt;get_sku()) ), $cart_item_key); ?&gt; &lt;/td&gt; &lt;/tr&gt; &lt;?php endif; ?&gt; &lt;?php endforeach; ?&gt; &lt;?php do_action(&#39;woocommerce_after_cart_contents&#39;); ?&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;?php do_action(&#39;woocommerce_after_cart_table&#39;); ?&gt; &lt;/form&gt; &lt;/div&gt; &lt;!-- Sticky Footer --&gt; &lt;div class=&quot;cart-footer-actions sticky-footer&quot; style=&quot;position: sticky; bottom: 0; background: white; padding: 15px; border-top: 1px solid #ddd; max-width: 1200px; margin: 0 auto;&quot;&gt; &lt;div style=&quot;display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;&quot;&gt; &lt;div class=&quot;footer-left&quot;&gt; &lt;input type=&quot;checkbox&quot; id=&quot;footer-select-all&quot;&gt; &lt;label for=&quot;footer-select-all&quot; style=&quot;display: inline-block; margin-left: 5px; cursor: pointer;&quot;&gt;全选&lt;/label&gt; &lt;button type=&quot;button&quot; class=&quot;button&quot; id=&quot;remove-selected-items&quot;&gt;刪除選中的商品&lt;/button&gt; &lt;button type=&quot;button&quot; class=&quot;button&quot; id=&quot;clear-cart&quot;&gt;清空購物車&lt;/button&gt; &lt;/div&gt; &lt;div class=&quot;coupon-section&quot;&gt; &lt;input type=&quot;text&quot; name=&quot;coupon_code&quot; class=&quot;input-text&quot; id=&quot;coupon_code&quot; value=&quot;&quot; placeholder=&quot;输入优惠券代码&quot; style=&quot;padding: 8px; width: 200px; border: 1px solid #ddd; border-radius: 4px; margin-right: 5px;&quot; /&gt; &lt;button type=&quot;button&quot; class=&quot;button&quot; id=&quot;apply-coupon&quot;&gt;应用优惠券&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div style=&quot;display: flex; justify-content: space-between; align-items: center;&quot;&gt; &lt;div class=&quot;selected-summary&quot; style=&quot;font-size: 16px; font-weight: bold;&quot;&gt; 已选商品: &lt;span id=&quot;selected-count&quot;&gt;0&lt;/span&gt; 件,共计: &lt;span id=&quot;selected-total&quot;&gt;RM0.00&lt;/span&gt; &lt;/div&gt; &lt;a href=&quot;&lt;?php echo esc_url( wc_get_checkout_url() ); ?&gt;&quot; class=&quot;checkout-button button alt wc-forward&quot; id=&quot;partial-checkout&quot;&gt;结算&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;?php do_action(&#39;woocommerce_after_cart&#39;); ?&gt; &lt;style&gt; /* Layout styles (unchanged) */ .cart-page-section { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); margin-bottom: 30px; } .cart-page-section table.cart { width: 100%; border-collapse: collapse; margin-bottom: 20px; } .cart-page-section table.cart th, .cart-page-section table.cart td { padding: 15px; text-align: left; border-bottom: 1px solid #eee; } .cart-page-section table.cart th { background-color: #f8f8f8; font-weight: bold; } .cart-page-section table.cart th.product-select, .cart-page-section table.cart td.product-select { width: 8%; text-align: center; vertical-align: middle; white-space: nowrap; } .cart-page-section table.cart td.product-info { width: 37%; vertical-align: top; } .cart-page-section table.cart .product-info .product-image { float: left; margin-right: 15px; width: 100px; height: 100px; } .cart-page-section table.cart .product-info .product-image img { max-width: 100%; height: auto; display: block; } .cart-page-section table.cart .product-info .product-name { overflow: hidden; } .cart-page-section table.cart td.product-price, .cart-page-section table.cart td.product-quantity, .cart-page-section table.cart td.product-subtotal { width: 15%; vertical-align: middle; } .cart-page-section table.cart td.product-remove { width: 5%; text-align: center; vertical-align: middle; } .cart-footer-actions { position: sticky; bottom: 0; background: #fff; padding: 15px; border-top: 1px solid #ddd; box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); z-index: 1000; display: flex; flex-direction: column; gap: 15px; } .footer-left { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; } .coupon-section { display: flex; align-items: center; gap: 5px; } .selected-summary { font-size: 16px; font-weight: bold; flex: 1; } .cart-footer-actions .button { padding: 10px 20px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; white-space: nowrap; } .cart-footer-actions .button:hover { background-color: #d32f2f; } #partial-checkout { padding: 12px 24px; background-color: #2196F3; color: white; text-decoration: none; border-radius: 4px; display: inline-block; transition: background-color 0.3s; white-space: nowrap; text-align: center; font-weight: bold; } #partial-checkout:hover { background-color: #0b7dda; } #coupon_code { padding: 8px; width: 200px; border: 1px solid #ddd; border-radius: 4px; transition: border-color 0.3s; } #coupon_code:focus { border-color: #2196F3; outline: none; } /* Responsive (unchanged) */ @media (max-width: 768px) { .cart-page-section table.cart thead { display: none; } .cart-page-section table.cart td { display: block; width: 100% !important; text-align: right; padding: 10px; position: relative; padding-left: 50%; } .cart-page-section table.cart td::before { content: attr(data-title); position: absolute; left: 15px; font-weight: bold; text-align: left; } .cart-page-section table.cart .product-info .product-image { float: none; margin: 0 auto 10px; } .cart-page-section table.cart td.product-select::before { content: &quot;选择&quot;; } .cart-footer-actions { flex-direction: column; align-items: flex-start; } .footer-left { width: 100%; justify-content: space-between; } .coupon-section { width: 100%; margin-top: 10px; } .coupon-section input { flex: 1; } .cart-footer-actions .footer-bottom-row { flex-direction: column; align-items: stretch; } .selected-summary { text-align: center; margin-bottom: 10px; } #partial-checkout { width: 100%; padding: 15px; } .cart-footer-actions .button { padding: 12px 15px; margin: 5px 0; width: 100%; text-align: center; } } @media (max-width: 480px) { .cart-page-section { padding: 15px; } .cart-page-section table.cart td { padding-left: 45%; } .cart-page-section table.cart td::before { font-size: 14px; } .cart-footer-actions { padding: 10px; } #coupon_code { width: 100%; } } /* Loader overlay above quantity input */ .product-quantity .quantity { position: relative; /* anchor for overlay */ } .quantity-saving-overlay { position: absolute; top: 0; left: 0; right: 0; height: 100%; display: none; /* hidden by default */ align-items: flex-start; /* appear at top */ justify-content: center;/* centered horizontally */ padding-top: 2px; background: rgba(255,255,255,0.0); /* transparent so it doesn&#39;t dim UI */ z-index: 10; pointer-events: none; /* don&#39;t block typing/clicks when visible */ } .quantity-saving-loader { width: 20px; height: 20px; border: 3px solid #f3f3f3; border-top: 3px solid #3498db; border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } &lt;/style&gt; &lt;script&gt; jQuery(function($){ // Context var PC = { ajax_url: (window.wc_cart_params &amp;&amp; window.wc_cart_params.ajax_url) || &#39;&lt;?php echo esc_url( admin_url(&quot;admin-ajax.php&quot;) ); ?&gt;&#39;, security: (function(){ var n = $(&#39;input[name=&quot;woocommerce-cart-nonce&quot;]&#39;).val(); if (n) return n; if (window.wc_cart_params &amp;&amp; window.wc_cart_params.cart_nonce) return window.wc_cart_params.cart_nonce; return &#39;&lt;?php echo wp_create_nonce(&quot;woocommerce-cart&quot;); ?&gt;&#39;; })(), cart_is_empty: &lt;?php echo $pc_cart_is_empty ? &#39;true&#39; : &#39;false&#39;; ?&gt;, cart_uid: &#39;&lt;?php echo esc_js($pc_uid); ?&gt;&#39; }; // Keys function lsKey(name){ return &#39;pc_&#39; + name + &#39;_&#39; + PC.cart_uid; } var LS_SELECTION = lsKey(&#39;selected_items&#39;); var LS_MASTER = lsKey(&#39;cart_master&#39;); // Utilities function getSelectedKeys(){ return $(&#39;.item-checkbox:checked&#39;).map(function(){ return this.value; }).get(); } function fmtRM(n){ n = isNaN(n) ? 0 : n; return &#39;RM&#39; + Number(n).toFixed(2); } // Selection persistence function readSelection(){ try { return JSON.parse(localStorage.getItem(LS_SELECTION) || &#39;[]&#39;); } catch(e){ return []; } } function writeSelection(keys){ try { localStorage.setItem(LS_SELECTION, JSON.stringify(keys||[])); } catch(e){} } function restoreSelectionFromLS(){ var saved = readSelection(); if (!Array.isArray(saved)) saved = []; $(&#39;.item-checkbox&#39;).each(function(){ $(this).prop(&#39;checked&#39;, saved.indexOf(this.value) !== -1); }); } window.addEventListener(&#39;storage&#39;, function(ev){ if (ev.key === LS_SELECTION) { restoreSelectionFromLS(); updateSelectedSummary(); } }); // Selected summary function updateSelectedSummary(){ var total = 0, count = 0; $(&#39;.item-checkbox:checked&#39;).each(function(){ var price = parseFloat($(this).data(&#39;price&#39;)); if (!isNaN(price)) { total += price; count++; } }); $(&#39;#selected-count&#39;).text(count); $(&#39;#selected-total&#39;).text(fmtRM(total)); var totalCbs = $(&#39;.item-checkbox&#39;).length; var checkedCbs = $(&#39;.item-checkbox:checked&#39;).length; var allChecked = totalCbs &gt; 0 &amp;&amp; checkedCbs === totalCbs; $(&#39;#select-all-items, #footer-select-all&#39;).prop(&#39;checked&#39;, allChecked); writeSelection(getSelectedKeys()); } // Select all $(&#39;#select-all-items, #footer-select-all&#39;).off(&#39;change.sc&#39;).on(&#39;change.sc&#39;, function(){ var checked = $(this).prop(&#39;checked&#39;); $(&#39;.item-checkbox&#39;).prop(&#39;checked&#39;, checked); updateSelectedSummary(); }); // 单个勾选项变化时,更新统计与&ldquo;全选&rdquo;状态 $(document).on(&#39;change&#39;, &#39;.item-checkbox&#39;, updateSelectedSummary); // Snapshot cart DOM -&gt; localStorage (guest resilience) function snapshotCartFromDOM() { var items = []; $(&#39;tr.cart_item&#39;).each(function(){ var $row = $(this); var pid = parseInt($row.attr(&#39;data-product_id&#39;),10)||0; var vid = parseInt($row.attr(&#39;data-variation_id&#39;),10)||0; var qty = parseFloat($row.find(&#39;input.qty&#39;).val())||0; var variation = {}; try { variation = JSON.parse($row.attr(&#39;data-variation&#39;)||&#39;{}&#39;); } catch(e){ variation = {}; } if (pid &amp;&amp; qty &gt; 0) { items.push({ product_id: pid, variation_id: vid, variation: variation, quantity: qty }); } }); try { localStorage.setItem(LS_MASTER, JSON.stringify({ ts: Date.now(), items: items })); } catch(e){} } function maybeRehydrateFromLocal() { if (!PC.cart_is_empty) return; var raw = localStorage.getItem(LS_MASTER); if (!raw) return; var data; try { data = JSON.parse(raw); } catch(e){ return; } var items = (data &amp;&amp; data.items) ? data.items : []; if (!items.length) return; $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;pc_rehydrate_cart&#39;, security: PC.security, items: JSON.stringify(items) } }).done(function(res){ if (res &amp;&amp; res.success) { location.reload(); // display rehydrated items } }); } // AFTER $(&#39;#remove-selected-items&#39;).off(&#39;click.sc&#39;).on(&#39;click.sc&#39;, function(){ var keys = getSelectedKeys(); if (!keys.length) { alert(&#39;请选择要删除的商品&#39;); return; } if (!confirm(&#39;确定要删除选中的商品吗?&#39;)) return; $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;remove_selected_cart_items&#39;, selected_items: keys, security: PC.security } }).done(function(res){ if (res &amp;&amp; res.success) { keys.forEach(function(k){ var $row = $(&#39;tr.cart_item[data-cart_item_key=&quot;&#39;+k+&#39;&quot;]&#39;); $row.fadeOut(250, function(){ $(this).remove(); snapshotCartFromDOM(); updateSelectedSummary(); }); }); // 从本地选择集合中剔除已删除项 var saved = readSelection().filter(function(k0){ return keys.indexOf(k0) === -1; }); writeSelection(saved); } else { alert((res &amp;&amp; res.data &amp;&amp; (res.data.message || res.data)) || &#39;删除失败,请重试&#39;); } }).fail(function(){ alert(&#39;删除失败,请重试&#39;); }); }); // Clear cart // AFTER $(&#39;#clear-cart&#39;).off(&#39;click.sc&#39;).on(&#39;click.sc&#39;, function(){ if (!confirm(&#39;确定要清空购物车吗?&#39;)) return; $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;empty_cart&#39;, security: PC.security } }).done(function(res){ if (res &amp;&amp; res.success) { writeSelection([]); localStorage.removeItem(LS_MASTER); location.reload(); } else { alert((res &amp;&amp; res.data &amp;&amp; (res.data.message || res.data)) || &#39;清空购物车失败,请重试&#39;); } }).fail(function(){ alert(&#39;清空购物车失败,请重试&#39;); }); }); // Apply coupon // AFTER $(&#39;#apply-coupon&#39;).off(&#39;click.sc&#39;).on(&#39;click.sc&#39;, function(){ var code = ($.trim($(&#39;#coupon_code&#39;).val()) || &#39;&#39;); if (!code) { alert(&#39;请输入优惠券代码&#39;); return; } var $btn = $(this).prop(&#39;disabled&#39;, true).text(&#39;处理中...&#39;); $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;apply_coupon&#39;, coupon_code: code, security: PC.security } }).done(function(res){ if (res &amp;&amp; res.success) { location.reload(); } else { alert((res &amp;&amp; res.data &amp;&amp; (res.data.message || res.data)) || &#39;优惠券应用失败,请重试&#39;); $btn.prop(&#39;disabled&#39;, false).text(&#39;应用优惠券&#39;); } }).fail(function(){ alert(&#39;发生错误,请重试&#39;); $btn.prop(&#39;disabled&#39;, false).text(&#39;应用优惠券&#39;); }); }); // ---- Quantity auto-save (fixed regex + loader above input) ---- // 已修正:正确的正则表达式 function parseCartKeyFromInputName(n) { var m = (n || &#39;&#39;).match(/^cart\[([a-zA-Z0-9_]+)\]\[qty\]$/); return m ? m[1] : null; } function ensureLoader($quantityContainer){ var $overlay = $quantityContainer.find(&#39;.quantity-saving-overlay&#39;); if (!$overlay.length) { $overlay = $(&#39;&lt;div class=&quot;quantity-saving-overlay&quot;&gt;&lt;div class=&quot;quantity-saving-loader&quot;&gt;&lt;/div&gt;&lt;/div&gt;&#39;); $quantityContainer.append($overlay); } return $overlay; } var qtyTimers = {}; $(document).on(&#39;input change&#39;, &#39;input.qty&#39;, function(){ var $input = $(this); var key = parseCartKeyFromInputName($input.attr(&#39;name&#39;)); if (!key) return; var $row = $input.closest(&#39;tr.cart_item&#39;); var $quantityContainer = $input.closest(&#39;.quantity&#39;); var val = parseInt($input.val(), 10); if (isNaN(val) || val &lt; 0) val = 0; // debounce if (qtyTimers[key]) clearTimeout(qtyTimers[key]); var $overlay = ensureLoader($quantityContainer); $overlay.hide(); qtyTimers[key] = setTimeout(function(){ $overlay.show(); $input.prop(&#39;disabled&#39;, true); $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;update_cart_item_qty&#39;, cart_item_key: key, qty: val, security: PC.security } }).done(function(res){ if (res &amp;&amp; res.success &amp;&amp; res.data){ if (res.data.subtotal_html) { $row.find(&#39;td.product-subtotal&#39;).html(res.data.subtotal_html); } var $cb = $row.find(&#39;.item-checkbox&#39;); if ($cb.length &amp;&amp; typeof res.data.line_total_incl_tax === &#39;number&#39;) { $cb.attr(&#39;data-price&#39;, res.data.line_total_incl_tax); } if (val === 0 || res.data.removed) { $row.fadeOut(300, function(){ $(this).remove(); snapshotCartFromDOM(); updateSelectedSummary(); }); } else { snapshotCartFromDOM(); updateSelectedSummary(); } } else { var msg = (res &amp;&amp; res.data &amp;&amp; (res.data.message || res.data)) || &#39;数量更新失败&#39;; alert(msg); } }).fail(function(){ alert(&#39;数量更新失败,请重试&#39;); }).always(function(){ $overlay.hide(); $input.prop(&#39;disabled&#39;, false); }); }, 500); // 0.5s debounce }); // Partial checkout -&gt; regular checkout page $(&#39;#partial-checkout&#39;).off(&#39;click.sc&#39;).on(&#39;click.sc&#39;, function(e){ e.preventDefault(); var keys = getSelectedKeys(); if (!keys.length) { alert(&#39;请至少选择一件商品结算&#39;); return; } var $btn = $(this), t = $btn.text(); $btn.prop(&#39;disabled&#39;, true).text(&#39;创建订单中...&#39;); snapshotCartFromDOM(); $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, dataType: &#39;json&#39;, data: { action: &#39;create_direct_order&#39;, selected_items: keys, security: PC.security } }).done(function(res){ if (res &amp;&amp; res.success &amp;&amp; res.data &amp;&amp; res.data.checkout_url) { window.location.href = res.data.checkout_url; // /checkout/?pc_token=... } else { alert((res &amp;&amp; res.data &amp;&amp; (res.data.message || res.data)) || &#39;创建订单失败,请重试&#39;); $btn.prop(&#39;disabled&#39;, false).text(t); } }).fail(function(xhr){ var msg = &#39;创建订单失败&#39;; if (xhr &amp;&amp; xhr.responseJSON &amp;&amp; xhr.responseJSON.data) { msg += &#39;:&#39; + (xhr.responseJSON.data.message || xhr.responseJSON.data); } alert(msg); $btn.prop(&#39;disabled&#39;, false).text(t); }); }); // Keep LS selection after clicking &quot;x&quot; remove; also snapshot $(document).on(&#39;click&#39;, &#39;a.remove&#39;, function(){ var key = $(this).closest(&#39;tr.cart_item&#39;).attr(&#39;data-cart_item_key&#39;); if (key) { var saved = readSelection().filter(function(k){ return k !== key; }); writeSelection(saved); snapshotCartFromDOM(); } }); // Init restoreSelectionFromLS(); updateSelectedSummary(); snapshotCartFromDOM(); maybeRehydrateFromLocal(); }); // NEW: Real-time cart count updater function updateHeaderCartCount() { $.ajax({ url: PC.ajax_url, method: &#39;POST&#39;, data: { action: &#39;get_cart_count&#39;, security: PC.security }, success: function(response) { if (response.success) { $(&#39;.cart-count&#39;).text(response.count); } } }); } // Update on cart changes $(document).on(&#39;cart_updated&#39;, function() { updateHeaderCartCount(); }); // Initial update updateHeaderCartCount(); }); &lt;/script&gt; functions.php &lt;?php defined(&#39;ABSPATH&#39;) || exit; /** * Robust partial checkout to regular /checkout/ with durable cart snapshot * - Snapshot full cart before virtualizing selection for checkout * - Do not remove anything until order is created * - On success (thank-you), rebuild cart as (snapshot - purchased) * - On cancel/back (visit cart), restore snapshot * - Guest resilience: localStorage + rehydrate AJAX */ /* ------------------------------------------------- * Helpers * ------------------------------------------------- */ /** * 新增:购物车数量AJAX端点 */ add_action(&#39;wp_ajax_get_cart_count&#39;, &#39;pc_get_cart_count&#39;); add_action(&#39;wp_ajax_nopriv_get_cart_count&#39;, &#39;pc_get_cart_count&#39;); function pc_get_cart_count() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $count = WC()-&gt;cart-&gt;get_cart_contents_count(); wp_send_json_success(array(&#39;count&#39; =&gt; $count)); } function pc_get_cart_uid() { if (is_user_logged_in()) { return &#39;user_&#39; . get_current_user_id(); } if (empty($_COOKIE[&#39;pc_cart_uid&#39;])) { $token = wp_generate_uuid4(); setcookie(&#39;pc_cart_uid&#39;, $token, time() + YEAR_IN_SECONDS, COOKIEPATH ?: &#39;/&#39;, &#39;&#39;, is_ssl(), false); $_COOKIE[&#39;pc_cart_uid&#39;] = $token; } return &#39;guest_&#39; . sanitize_text_field(wp_unslash($_COOKIE[&#39;pc_cart_uid&#39;])); } function pc_build_item_key($product_id, $variation_id = 0) { return (int)$product_id . &#39;|&#39; . (int)$variation_id; } function pc_snapshot_current_cart() { if (!WC()-&gt;cart) wc_load_cart(); $items = array(); foreach (WC()-&gt;cart-&gt;get_cart() as $ci_key =&gt; $ci) { $pid = isset($ci[&#39;product_id&#39;]) ? (int)$ci[&#39;product_id&#39;] : 0; $vid = isset($ci[&#39;variation_id&#39;]) ? (int)$ci[&#39;variation_id&#39;] : 0; $qty = isset($ci[&#39;quantity&#39;]) ? wc_stock_amount($ci[&#39;quantity&#39;]) : 0; $var = isset($ci[&#39;variation&#39;]) &amp;&amp; is_array($ci[&#39;variation&#39;]) ? $ci[&#39;variation&#39;] : array(); if ($pid &amp;&amp; $qty &gt; 0) { $items[] = array( &#39;product_id&#39; =&gt; $pid, &#39;variation_id&#39; =&gt; $vid, &#39;variation&#39; =&gt; array_map(&#39;wc_clean&#39;, $var), &#39;quantity&#39; =&gt; $qty, ); } } return $items; } function pc_restore_cart_from_items($items) { if (!WC()-&gt;cart) wc_load_cart(); WC()-&gt;cart-&gt;empty_cart(); foreach ((array)$items as $it) { $pid = isset($it[&#39;product_id&#39;]) ? (int)$it[&#39;product_id&#39;] : 0; $vid = isset($it[&#39;variation_id&#39;]) ? (int)$it[&#39;variation_id&#39;] : 0; $qty = isset($it[&#39;quantity&#39;]) ? wc_stock_amount($it[&#39;quantity&#39;]) : 0; $var = isset($it[&#39;variation&#39;]) &amp;&amp; is_array($it[&#39;variation&#39;]) ? array_map(&#39;wc_clean&#39;, $it[&#39;variation&#39;]) : array(); if ($pid &amp;&amp; $qty &gt; 0) { WC()-&gt;cart-&gt;add_to_cart($pid, $qty, $vid, $var); } } WC()-&gt;cart-&gt;calculate_totals(); } // Fix cart restoration logic add_action(&#39;wp_loaded&#39;, function() { if (!method_exists(WC()-&gt;session, &#39;get&#39;)) return; $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if ($token &amp;&amp; WC()-&gt;cart-&gt;is_empty()) { $payload = get_transient(pc_transient_key($token)); if (!empty($payload[&#39;snapshot&#39;])) { pc_restore_cart_from_items($payload[&#39;snapshot&#39;]); WC()-&gt;cart-&gt;calculate_totals(); } } }, 20); function pc_transient_key($token) { return &#39;pc_partial_payload_&#39; . sanitize_key($token); } /* ------------------------------------------------- * AJAX: Local rehydrate when Woo cart is empty * ------------------------------------------------- */ add_action(&#39;wp_ajax_pc_rehydrate_cart&#39;, &#39;pc_rehydrate_cart&#39;); add_action(&#39;wp_ajax_nopriv_pc_rehydrate_cart&#39;, &#39;pc_rehydrate_cart&#39;); function pc_rehydrate_cart() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $raw = isset($_POST[&#39;items&#39;]) ? wp_unslash($_POST[&#39;items&#39;]) : &#39;&#39;; $items = is_string($raw) ? json_decode($raw, true) : (array)$raw; if (!is_array($items)) { wp_send_json_error(array(&#39;message&#39; =&gt; &#39;Invalid items.&#39;), 400); } if (!WC()-&gt;cart) wc_load_cart(); if (!WC()-&gt;cart-&gt;is_empty()) { wp_send_json_success(array(&#39;message&#39; =&gt; &#39;Cart not empty.&#39;)); } foreach ($items as $it) { $pid = isset($it[&#39;product_id&#39;]) ? (int)$it[&#39;product_id&#39;] : 0; $vid = isset($it[&#39;variation_id&#39;]) ? (int)$it[&#39;variation_id&#39;] : 0; $qty = isset($it[&#39;quantity&#39;]) ? wc_stock_amount($it[&#39;quantity&#39;]) : 0; $var = isset($it[&#39;variation&#39;]) &amp;&amp; is_array($it[&#39;variation&#39;]) ? array_map(&#39;wc_clean&#39;, $it[&#39;variation&#39;]) : array(); if ($pid &amp;&amp; $qty &gt; 0) { WC()-&gt;cart-&gt;add_to_cart($pid, $qty, $vid, $var); } } WC()-&gt;cart-&gt;calculate_totals(); wp_send_json_success(array(&#39;rehydrated&#39; =&gt; true)); } /* ------------------------------------------------- * AJAX: Update qty (per-row; no page reload) * ------------------------------------------------- */ add_action(&#39;wp_ajax_update_cart_item_qty&#39;, &#39;pc_update_cart_item_qty&#39;); add_action(&#39;wp_ajax_nopriv_update_cart_item_qty&#39;, &#39;pc_update_cart_item_qty&#39;); function pc_update_cart_item_qty() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $key = isset($_POST[&#39;cart_item_key&#39;]) ? wc_clean(wp_unslash($_POST[&#39;cart_item_key&#39;])) : &#39;&#39;; $qty = isset($_POST[&#39;qty&#39;]) ? wc_stock_amount($_POST[&#39;qty&#39;]) : null; if (!$key || $qty === null) { wp_send_json_error(array(&#39;message&#39; =&gt; &#39;Missing params.&#39;), 400); } if (!WC()-&gt;cart) wc_load_cart(); if ($qty &lt;= 0) { $removed = WC()-&gt;cart-&gt;remove_cart_item($key); WC()-&gt;cart-&gt;calculate_totals(); wp_send_json_success(array(&#39;removed&#39; =&gt; (bool)$removed)); } else { $set = WC()-&gt;cart-&gt;set_quantity($key, $qty, true); WC()-&gt;cart-&gt;calculate_totals(); $cart_item = WC()-&gt;cart-&gt;get_cart_item($key); if (!$cart_item) { wp_send_json_error(array(&#39;message&#39; =&gt; &#39;Cart item not found after update.&#39;), 404); } $_product = $cart_item[&#39;data&#39;]; $subtotal_html = apply_filters( &#39;woocommerce_cart_item_subtotal&#39;, WC()-&gt;cart-&gt;get_product_subtotal($_product, $cart_item[&#39;quantity&#39;]), $cart_item, $key ); // Use line_total + line_tax (after totals) for checkbox data-price $line_total_incl_tax = (float)($cart_item[&#39;line_total&#39;] + $cart_item[&#39;line_tax&#39;]); wp_send_json_success(array( &#39;subtotal_html&#39; =&gt; $subtotal_html, &#39;line_total_incl_tax&#39; =&gt; $line_total_incl_tax, &#39;removed&#39; =&gt; false, )); } } /* ------------------------------------------------- * AJAX: Remove selected * ------------------------------------------------- */ add_action(&#39;wp_ajax_remove_selected_cart_items&#39;, &#39;pc_remove_selected_cart_items&#39;); add_action(&#39;wp_ajax_nopriv_remove_selected_cart_items&#39;, &#39;pc_remove_selected_cart_items&#39;); function pc_remove_selected_cart_items() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $keys = isset($_POST[&#39;selected_items&#39;]) ? (array) $_POST[&#39;selected_items&#39;] : array(); if (!WC()-&gt;cart) wc_load_cart(); foreach ($keys as $k) { $k = wc_clean(wp_unslash($k)); WC()-&gt;cart-&gt;remove_cart_item($k); } WC()-&gt;cart-&gt;calculate_totals(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Empty cart * ------------------------------------------------- */ add_action(&#39;wp_ajax_empty_cart&#39;, &#39;pc_empty_cart&#39;); add_action(&#39;wp_ajax_nopriv_empty_cart&#39;, &#39;pc_empty_cart&#39;); function pc_empty_cart() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); if (!WC()-&gt;cart) wc_load_cart(); WC()-&gt;cart-&gt;empty_cart(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Apply coupon * ------------------------------------------------- */ add_action(&#39;wp_ajax_apply_coupon&#39;, &#39;pc_apply_coupon&#39;); add_action(&#39;wp_ajax_nopriv_apply_coupon&#39;, &#39;pc_apply_coupon&#39;); function pc_apply_coupon() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $code = isset($_POST[&#39;coupon_code&#39;]) ? wc_format_coupon_code(wp_unslash($_POST[&#39;coupon_code&#39;])) : &#39;&#39;; if (!$code) { wp_send_json_error(array(&#39;message&#39; =&gt; __(&#39;请输入优惠券代码&#39;, &#39;woocommerce&#39;)), 400); } if (!WC()-&gt;cart) wc_load_cart(); $applied = WC()-&gt;cart-&gt;apply_coupon($code); WC()-&gt;cart-&gt;calculate_totals(); if (is_wp_error($applied)) { wp_send_json_error(array(&#39;message&#39; =&gt; $applied-&gt;get_error_message()), 400); } if (!$applied) { wp_send_json_error(array(&#39;message&#39; =&gt; __(&#39;优惠券应用失败&#39;, &#39;woocommerce&#39;)), 400); } wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Start partial checkout to regular checkout page * ------------------------------------------------- */ add_action(&#39;wp_ajax_create_direct_order&#39;, &#39;pc_create_direct_order&#39;); add_action(&#39;wp_ajax_nopriv_create_direct_order&#39;, &#39;pc_create_direct_order&#39;); function pc_create_direct_order() { check_ajax_referer(&#39;woocommerce-cart&#39;, &#39;security&#39;); $selected_keys = isset($_POST[&#39;selected_items&#39;]) ? (array) $_POST[&#39;selected_items&#39;] : array(); if (empty($selected_keys)) { wp_send_json_error(array(&#39;message&#39; =&gt; __(&#39;请选择要结算的商品&#39;, &#39;woocommerce&#39;)), 400); } if (!WC()-&gt;cart) wc_load_cart(); // Snapshot full cart $snapshot = pc_snapshot_current_cart(); // Build selected items from current cart based on cart_item_key list $selected = array(); foreach (WC()-&gt;cart-&gt;get_cart() as $ci_key =&gt; $ci) { if (!in_array($ci_key, $selected_keys, true)) { continue; } $pid = (int)$ci[&#39;product_id&#39;]; $vid = (int)$ci[&#39;variation_id&#39;]; $qty = wc_stock_amount($ci[&#39;quantity&#39;]); $var = isset($ci[&#39;variation&#39;]) &amp;&amp; is_array($ci[&#39;variation&#39;]) ? array_map(&#39;wc_clean&#39;, $ci[&#39;variation&#39;]) : array(); if ($pid &amp;&amp; $qty &gt; 0) { $selected[] = array( &#39;product_id&#39; =&gt; $pid, &#39;variation_id&#39; =&gt; $vid, &#39;variation&#39; =&gt; $var, &#39;quantity&#39; =&gt; $qty, ); } } if (empty($selected)) { wp_send_json_error(array(&#39;message&#39; =&gt; __(&#39;没有可结算的商品&#39;, &#39;woocommerce&#39;)), 400); } $token = wp_generate_uuid4(); $payload = array( &#39;uid&#39; =&gt; pc_get_cart_uid(), &#39;snapshot&#39; =&gt; $snapshot, &#39;selected&#39; =&gt; $selected, &#39;created&#39; =&gt; time(), ); set_transient(pc_transient_key($token), $payload, 2 * DAY_IN_SECONDS); // Put token in session (used across checkout AJAX calls) if (method_exists(WC()-&gt;session, &#39;set&#39;)) { WC()-&gt;session-&gt;set(&#39;pc_partial_token&#39;, $token); } $checkout_url = add_query_arg(&#39;pc_token&#39;, rawurlencode($token), wc_get_checkout_url()); wp_send_json_success(array(&#39;checkout_url&#39; =&gt; $checkout_url)); } /* ------------------------------------------------- * Virtualize cart on checkout for token and rebuild after purchase * ------------------------------------------------- */ // Entering checkout with token: virtualize cart to selected items add_action(&#39;woocommerce_before_checkout_form&#39;, function() { if (!isset($_GET[&#39;pc_token&#39;])) return; $token = sanitize_text_field(wp_unslash($_GET[&#39;pc_token&#39;])); $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload[&#39;selected&#39;])) return; if (!WC()-&gt;cart) wc_load_cart(); // Virtualize to selected items only pc_restore_cart_from_items($payload[&#39;selected&#39;]); // Persist token in session for all subsequent checkout AJAX calls if (method_exists(WC()-&gt;session, &#39;set&#39;)) { WC()-&gt;session-&gt;set(&#39;pc_partial_token&#39;, $token); } }, 1); // Safety: just-in-time re-virtualization before order processing add_action(&#39;woocommerce_before_checkout_process&#39;, function() { if (!method_exists(WC()-&gt;session, &#39;get&#39;)) return; $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload[&#39;selected&#39;])) return; // Ensure cart still equals selected set pc_restore_cart_from_items($payload[&#39;selected&#39;]); }, 1); // Tag order with token add_action(&#39;woocommerce_checkout_create_order&#39;, function($order) { $token = null; if (isset($_GET[&#39;pc_token&#39;])) { $token = sanitize_text_field(wp_unslash($_GET[&#39;pc_token&#39;])); } elseif (method_exists(WC()-&gt;session, &#39;get&#39;)) { $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); } if ($token) { $order-&gt;update_meta_data(&#39;_pc_partial_token&#39;, $token); $order-&gt;update_meta_data(&#39;_pc_cart_snapshot&#39;, $token); } }, 10, 1); // Fixed: Only remove purchased items from cart add_action(&#39;woocommerce_thankyou&#39;, function($order_id) { $order = wc_get_order($order_id); if (!$order) return; $token = $order-&gt;get_meta(&#39;_pc_partial_token&#39;); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload[&#39;snapshot&#39;])) { if (method_exists(WC()-&gt;session, &#39;set&#39;)) { WC()-&gt;session-&gt;set(&#39;pc_partial_token&#39;, null); } delete_transient(pc_transient_key($token)); return; } // 1. Restore FULL snapshot (all items) pc_restore_cart_from_items($payload[&#39;snapshot&#39;]); WC()-&gt;cart-&gt;calculate_totals(); // 2. Remove only the purchased (selected) items foreach ($payload[&#39;selected&#39;] as $selected_item) { $cart_item_key = pc_find_cart_item($selected_item[&#39;product_id&#39;], $selected_item[&#39;variation_id&#39;]); if ($cart_item_key) { WC()-&gt;cart-&gt;remove_cart_item($cart_item_key); } } // 3. Update cart totals WC()-&gt;cart-&gt;calculate_totals(); // Cleanup token if (method_exists(WC()-&gt;session, &#39;set&#39;)) { WC()-&gt;session-&gt;set(&#39;pc_partial_token&#39;, null); } delete_transient(pc_transient_key($token)); }, 20); // Helper: Find cart item by product and variation ID function pc_find_cart_item($product_id, $variation_id = 0) { if (!WC()-&gt;cart) wc_load_cart(); foreach (WC()-&gt;cart-&gt;get_cart() as $cart_item_key =&gt; $cart_item) { $cart_pid = isset($cart_item[&#39;product_id&#39;]) ? (int)$cart_item[&#39;product_id&#39;] : 0; $cart_vid = isset($cart_item[&#39;variation_id&#39;]) ? (int)$cart_item[&#39;variation_id&#39;] : 0; if ($cart_pid == $product_id &amp;&amp; $cart_vid == $variation_id) { return $cart_item_key; } } return false; } // Visiting cart with active token: restore full snapshot (cancel/back) add_action(&#39;woocommerce_before_cart&#39;, function() { if (!method_exists(WC()-&gt;session, &#39;get&#39;)) return; $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload[&#39;snapshot&#39;])) return; // Restore full snapshot so cart page always shows everything pc_restore_cart_from_items($payload[&#39;snapshot&#39;]); }, 1); /* ------------------------------------------------- * Keep cart count accurate during checkout process * ------------------------------------------------- */ add_filter(&#39;woocommerce_cart_contents_count&#39;, function($count) { // Check if partial token exists if (!method_exists(WC()-&gt;session, &#39;get&#39;)) return $count; $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if ($token) { $payload = get_transient(pc_transient_key($token)); // Always show full cart count even during checkout if (!empty($payload[&#39;snapshot&#39;])) { $snapshot_count = 0; foreach ($payload[&#39;snapshot&#39;] as $item) { $snapshot_count += (int)$item[&#39;quantity&#39;]; } return $snapshot_count; } } return $count; }); // Ensure cart item totals are accurate in header add_action(&#39;woocommerce_before_cart&#39;, function() { pc_maintain_cart_consistency(); }); add_action(&#39;woocommerce_before_checkout_form&#39;, function() { pc_maintain_cart_consistency(); }); function pc_maintain_cart_consistency() { if (!method_exists(WC()-&gt;session, &#39;get&#39;)) return; $token = WC()-&gt;session-&gt;get(&#39;pc_partial_token&#39;); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload[&#39;snapshot&#39;])) return; // Immediately restore full cart for consistent UI pc_restore_cart_from_items($payload[&#39;snapshot&#39;]); WC()-&gt;cart-&gt;calculate_totals(); }
最新发布
09-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值