diff --git a/assets/css/routes/user-center/credits.css b/assets/css/routes/user-center/credits.css index 701b5325..353bfa93 100644 --- a/assets/css/routes/user-center/credits.css +++ b/assets/css/routes/user-center/credits.css @@ -157,65 +157,64 @@ margin-left: 6px; } -/* Charge packages */ -.uc-charge-packages { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 10px; - margin-bottom: 8px; +/* ===== 余额充值弹窗 — Zibll balance-charge modal parity ===== + .zib-widget 基础卡样式与 .vip-product/.vip-tag 的 Zibll 原值仅在充值表单内生效 + (vip-modal.css 在全局以同类名覆盖了它们,这里按 Zibll main.css 5962/5928/5990 回位)。 */ +.balance-charge-form .zib-widget { + clear: both; + background-color: var(--main-bg-color); + padding: 15px; + box-shadow: 0 0 10px var(--main-shadow); + border-radius: var(--main-radius); + margin-bottom: 20px; } -.uc-charge-package { - position: relative; - display: block; - padding: 12px; - border: 1px solid var(--color-line, rgba(0, 0, 0, 0.08)); - border-radius: 8px; - cursor: pointer; - background: var(--surface-1, #fff); -} -.uc-charge-package input { - position: absolute; - opacity: 0; - pointer-events: none; -} -.uc-charge-package.is-active, -.uc-charge-package:has(input:checked) { - border-color: var(--focus-color, #f04494); - box-shadow: 0 0 0 1px var(--focus-color, #f04494); -} -.uc-charge-package__credit { - font-size: 1.25rem; - font-weight: 700; -} -.uc-charge-package__tag { - position: absolute; - top: 0; - right: 0; - font-size: 11px; - padding: 2px 8px; - border-radius: 0 8px 0 8px; - background: #fbbf24; - color: #333; -} -.uc-charge-custom__input { - flex: 1; - min-width: 0; - border: 0; - border-bottom: 1px solid var(--color-line, #ddd); - padding: 6px 0; - font-size: 1.1rem; - outline: none; -} -.uc-charge-methods { - display: flex; - flex-wrap: wrap; - gap: 10px; -} -.uc-charge-method { +.balance-charge-form .vip-product { + border: 1px solid var(--main-border-color); + box-shadow: none; + background-color: var(--main-bg-color); + min-width: 66px; + min-height: 65px; display: inline-flex; + flex-direction: column; + justify-content: space-evenly; align-items: center; - gap: 6px; + margin: 8px; + font-weight: normal; + gap: 10px; + padding: 15px 4px 10px; cursor: pointer; + transition: 0.15s; + position: relative; + overflow: unset; + border-radius: var(--mini-radius); +} +.balance-charge-form .vip-product.active { + border-color: var(--focus-color); + background: var(--focus-color-opacity05); + box-shadow: none; +} +.balance-charge-form .vip-product.active::before { + content: '\f058'; + font: normal normal normal 16px/1 FontAwesome; + color: var(--focus-color); + position: absolute; + left: 3px; + top: 3px; + font-size: 18px; +} +.balance-charge-form .vip-product .vip-tag { + position: absolute; + font-size: 12px; + padding: 1px 5px; + border-radius: 100px; + right: -14px; + top: -10px; + transform: scale(0.9); + background: var(--this-bg); + color: var(--this-color); + line-height: 1.4; + width: auto; + z-index: 1; } /* Modal shell */ diff --git a/assets/js/credits.js b/assets/js/credits.js index 3f86bd4e..637dd071 100644 --- a/assets/js/credits.js +++ b/assets/js/credits.js @@ -393,19 +393,63 @@ modal.dataset.aksrtChargeInitialized = '1'; var form = modal.querySelector('[data-aksrt-charge-form]'); var busy = false; + var jq = window.jQuery; + document.querySelectorAll('[data-aksrt-charge-open]').forEach(function (btn) { - btn.addEventListener('click', function () { openModal(modal); }); - }); - modal.querySelectorAll('[data-aksrt-charge-close]').forEach(function (btn) { btn.addEventListener('click', function () { - closeModal(modal); + // Zibll 弹窗壳(.modal.fade)走 Bootstrap modal 运行时(zibll 的 refresh_modal 同源行为)。 + if (jq && jq.fn && jq.fn.modal) { + jq(modal).modal('show'); + } else { + modal.style.display = 'block'; + modal.classList.add('in'); + } }); }); - modal.querySelectorAll('.uc-charge-package input').forEach(function (inp) { - inp.addEventListener('change', function () { - modal.querySelectorAll('.uc-charge-package').forEach(function (el) { - el.classList.toggle('is-active', el.contains(inp) && inp.checked); - }); + if (jq && jq.fn && jq.fn.modal) { + jq(modal).on('hidden.bs.modal', function () { + if (activePoll && typeof activePoll.abort === 'function') { + activePoll.abort(); + notyf('已停止查询支付状态', 'warning', 3, 'aksrt-balance-charge-payment-toast'); + } + activePoll = null; + }); + } + // Zibll data-for/data-value 选中模型:余额档位(.vip-product.product-box) + // 选中变化不产生 change 事件(隐藏 input 由程序赋值),需显式重置幂等键。 + function selectProduct(value) { + modal.querySelectorAll('[data-for="balance_product"]').forEach(function (el) { + el.classList.toggle('active', el.getAttribute('data-value') === value); + }); + var hidden = modal.querySelector('input[name="balance_product"]'); + if (hidden) hidden.value = value; + if (form) resetOperationKey(form); + } + modal.querySelectorAll('[data-for="balance_product"]').forEach(function (el) { + el.addEventListener('click', function () { + selectProduct(el.getAttribute('data-value')); + }); + }); + var customInput = modal.querySelector('input[name="custom_price"]'); + if (customInput) { + customInput.addEventListener('input', function () { + if (String(customInput.value || '').trim() !== '') { + selectProduct('custom'); + } + }); + } + // 支付方式(.payment-method-radio) + function selectMethod(value) { + modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) { + el.classList.toggle('active', el.getAttribute('data-value') === value); + }); + var hidden = modal.querySelector('input[name="payment_method"]'); + if (hidden) hidden.value = value; + if (form) resetOperationKey(form); + } + modal.querySelectorAll('[data-for="payment_method"]').forEach(function (el) { + el.addEventListener('click', function () { + selectMethod(el.getAttribute('data-value')); }); }); if (!form) return; @@ -413,24 +457,25 @@ form.addEventListener('submit', function (e) { e.preventDefault(); if (busy) return; - var pkgInput = form.querySelector('input[name="balance_package"]:checked') || form.querySelector('input[name="balance_package"]'); + var pkgInput = form.querySelector('input[name="balance_product"]'); var pkg = pkgInput ? pkgInput.value : 'custom'; var customEl = form.querySelector('input[name="custom_price"]'); var custom = customEl ? String(customEl.value || '').trim() : ''; var validCustom = /^(0|[1-9]\d*)(?:\.\d{1,2})?$/.test(custom) && custom !== '0' && custom !== '0.0' && custom !== '0.00'; if (validCustom) { pkg = 'custom'; + selectProduct('custom'); } - if ((!pkg || pkg === 'custom') && !validCustom && !pkgInput) { + if ((!pkg || pkg === 'custom') && !validCustom) { notyf('请选择或输入充值金额', 'danger'); return; } - if (pkg === 'custom' && !validCustom) { - notyf('请输入有效充值金额', 'danger'); + var methodEl = form.querySelector('input[name="payment_method"]'); + var method = methodEl ? methodEl.value : ''; + if (!method) { + notyf('暂无可用支付方式', 'danger'); return; } - var methodEl = form.querySelector('input[name="payment_method"]:checked'); - var method = methodEl ? methodEl.value : 'alipay'; busy = true; notyf('正在创建充值订单…', 'load', '', 'aksrt-balance-charge-toast'); api('/pay/balance/charge', { diff --git a/inc/helpers/user-center-renderers/credits-wallet.php b/inc/helpers/user-center-renderers/credits-wallet.php index 7c48543e..184d4460 100644 --- a/inc/helpers/user-center-renderers/credits-wallet.php +++ b/inc/helpers/user-center-renderers/credits-wallet.php @@ -129,61 +129,102 @@ $mark = (string) ($charge_view['currency_mark'] ?? '元'); - -