fix(vip): 会员弹窗支付方式渠道对齐 Zibll initiate_pay_input 组件
支付方式 UI 不再自实现(uc-vip-shop__method 文本 radio),改为与其他 两个弹窗(充值/积分)完全同源的 Zibll zibpay_get_initiate_pay_input 组件结构: - 支付方式行:.payment-method-radio.hollow-radio + logo 图 + data-for/data-value 选中模型(多渠道时展示「请选择支付方式」) - 我的余额盒:data-controller == balance 条件显隐,展示货币符号与余额 (视图模型透传 wallet_balance / currency_mark) - 卡密盒:Zibll password_box 同构(mb10 padding-h10 padding-w6 + desc muted-box + form-control 卡号/卡密输入) - hidden payment_method + initiate-pay 按钮类(mt6 but jb-red btn-block radius) - 服务端 payment_method_logo_url() 统一映射 pay-*-logo.svg - 显隐统一走 data-controller(==/!=)通用匹配,卡密选中隐藏 .charge-box - 清理 uc-vip-shop__method* 死样式与旧 change 监听;契约测试同步锁定 (.gitignore 白名单补 card-pass-modal-redeem.test.cjs)
This commit is contained in:
+78
-41
@@ -102,43 +102,64 @@
|
||||
append(parent, wrap);
|
||||
}
|
||||
|
||||
function renderMethods(parent, methods, cardPass) {
|
||||
function renderMethods(parent, methods, cardPass, wallet) {
|
||||
methods = Array.isArray(methods) ? methods : [];
|
||||
if (!methods.length) {
|
||||
append(parent, node("div", "muted-2-color text-center padding-10", "暂无可用支付方式"));
|
||||
return;
|
||||
}
|
||||
if (methods.length === 1) {
|
||||
var one = node("input");
|
||||
one.type = "hidden";
|
||||
one.name = "aksrt_vip_pay_method";
|
||||
one.value = text(methods[0].id || "balance");
|
||||
one.setAttribute("data-aksrt-vip-method-fixed", "");
|
||||
append(parent, one);
|
||||
} else {
|
||||
var wrap = node("div", "uc-vip-shop__methods mb10");
|
||||
wrap.setAttribute("data-aksrt-vip-methods", "");
|
||||
append(wrap, node("span", "uc-vip-shop__methods-label", "支付方式"));
|
||||
wallet = wallet || {};
|
||||
var defaultMethod = text(methods[0].id || "balance");
|
||||
|
||||
// 支付方式选择行(Zibll zibpay_get_initiate_pay_input 同构:
|
||||
// .payment-method-radio.hollow-radio + logo 图 + data-for 选中模型;
|
||||
// 与余额充值/购买积分弹窗完全一致的组件)。
|
||||
if (methods.length > 1) {
|
||||
append(parent, node("div", "muted-2-color em09 mb6", "请选择支付方式"));
|
||||
var row = node("div", "flex mb10");
|
||||
methods.forEach(function (method, index) {
|
||||
var label = node("label", "uc-vip-shop__method");
|
||||
var input = node("input");
|
||||
input.type = "radio";
|
||||
input.name = "aksrt_vip_pay_method";
|
||||
input.value = text(method.id || "balance");
|
||||
input.checked = index === 0;
|
||||
append(label, input);
|
||||
append(label, node("span", "", method.name || method.id || ""));
|
||||
append(wrap, label);
|
||||
var id = text(method.id || "balance");
|
||||
var item = node("div", "flex jc hh payment-method-radio hollow-radio flex-auto pointer" + (index === 0 ? " active" : ""));
|
||||
item.setAttribute("data-for", "payment_method");
|
||||
item.setAttribute("data-value", id);
|
||||
if (method.logo) {
|
||||
var img = node("img");
|
||||
img.src = text(method.logo);
|
||||
img.alt = id + "-logo";
|
||||
img.decoding = "async";
|
||||
append(item, img);
|
||||
}
|
||||
append(item, node("div", "", method.name || id || ""));
|
||||
append(row, item);
|
||||
});
|
||||
append(parent, wrap);
|
||||
append(parent, row);
|
||||
}
|
||||
// 卡密渠道输入盒(契约与参考主题一致:data-controller="payment_method")。
|
||||
|
||||
// 我的余额盒(Zibll user_balance_box 同构:选中余额渠道时显示)。
|
||||
if (methods.some(function (m) { return text(m.id) === "balance"; })) {
|
||||
var balanceBox = node("div", "mb10 muted-box padding-h10");
|
||||
balanceBox.setAttribute("data-controller", "payment_method");
|
||||
balanceBox.setAttribute("data-condition", "==");
|
||||
balanceBox.setAttribute("data-value", "balance");
|
||||
if (defaultMethod !== "balance") balanceBox.style.display = "none";
|
||||
var balanceRow = node("div", "flex jsb ac");
|
||||
append(balanceRow, node("span", "muted-2-color", "我的余额"));
|
||||
var balanceValue = node("div", "c-blue-2");
|
||||
append(balanceValue, node("span", "px12 mr3", wallet.mark || "¥"));
|
||||
append(balanceValue, node("span", "em14", text(wallet.balance || "0.00")));
|
||||
append(balanceRow, balanceValue);
|
||||
append(balanceBox, balanceRow);
|
||||
append(parent, balanceBox);
|
||||
}
|
||||
|
||||
// 卡密盒(Zibll password_box 同构:mb10 padding-h10 padding-w6 +
|
||||
// data-controller="payment_method" 契约 + form-control 输入)。
|
||||
if (cardPass) {
|
||||
var box = node("div", "uc-vip-shop__card-pass mb10");
|
||||
var box = node("div", "mb10 padding-h10 padding-w6");
|
||||
box.setAttribute("data-controller", "payment_method");
|
||||
box.setAttribute("data-condition", "==");
|
||||
box.setAttribute("data-value", "card_pass");
|
||||
box.style.display = "none";
|
||||
if (defaultMethod !== "card_pass") box.style.display = "none";
|
||||
if (cardPass.desc) append(box, node("div", "muted-box muted-2-color padding-10 mb10 em09", cardPass.desc));
|
||||
append(box, node("div", "muted-2-color em09 mb6", cardPass.only_password ? "请输入卡密" : "请输入卡号和密码"));
|
||||
if (!cardPass.only_password) {
|
||||
@@ -157,15 +178,26 @@
|
||||
append(box, pwInput);
|
||||
append(parent, box);
|
||||
}
|
||||
|
||||
var hidden = node("input");
|
||||
hidden.type = "hidden";
|
||||
hidden.name = "payment_method";
|
||||
hidden.value = defaultMethod;
|
||||
append(parent, hidden);
|
||||
}
|
||||
|
||||
// 卡密渠道显隐:选中 card_pass 时隐藏套餐(.charge-box)、显示卡密输入盒。
|
||||
// 渠道显隐:通用 data-controller 契约(==/!= 匹配当前 payment_method);
|
||||
// 选中 card_pass 时隐藏套餐(.charge-box),与参考主题 pay.js 行为一致。
|
||||
function applyVipMethodVisibility(root) {
|
||||
var pane = root.closest ? root.closest(".aksrt-vip-pane") : null;
|
||||
pane = pane || root;
|
||||
var value = selectedMethod(pane);
|
||||
var cardBox = pane.querySelector('[data-controller="payment_method"][data-value="card_pass"]');
|
||||
if (cardBox) cardBox.style.display = value === "card_pass" ? "" : "none";
|
||||
pane.querySelectorAll('[data-controller="payment_method"]').forEach(function (el) {
|
||||
var condition = el.getAttribute("data-condition") || "==";
|
||||
var target = el.getAttribute("data-value") || "";
|
||||
var match = condition === "!=" ? value !== target : value === target;
|
||||
el.style.display = match ? "" : "none";
|
||||
});
|
||||
pane.querySelectorAll(".charge-box").forEach(function (el) {
|
||||
el.style.display = value === "card_pass" ? "none" : "";
|
||||
});
|
||||
@@ -286,6 +318,7 @@
|
||||
var groups = Array.isArray(catalog.level_packages) ? catalog.level_packages : [];
|
||||
var methods = Array.isArray(view.payment_methods) ? view.payment_methods : [];
|
||||
var cardPass = view.card_pass && view.card_pass.enabled ? view.card_pass : null;
|
||||
var wallet = { balance: text(catalog.wallet_balance || "0.00"), mark: text(view.currency_mark || "¥") };
|
||||
var allowed = view.allowed_actions || {};
|
||||
var reasons = view.action_reasons || {};
|
||||
var modal = node("div", "box-body payvip-modal");
|
||||
@@ -365,12 +398,12 @@
|
||||
|
||||
var products = node("div", "pay-vip-products");
|
||||
renderProducts(products, group.items);
|
||||
renderMethods(products, methods);
|
||||
renderMethods(products, methods, cardPass, wallet);
|
||||
var actionName = actionKey(action);
|
||||
var actionAllowed = allowed[actionName] === true;
|
||||
var reason = actionReason(reasons[actionName]);
|
||||
var canPurchase = actionAllowed && methods.length > 0;
|
||||
var submit = node("button", "but jb-red btn-block padding-lg radius aksrt-vip-submit", canPurchase ? (group.items[0].cta_label || actionLabel(action)) : (reason || "暂无可用支付方式"));
|
||||
var submit = node("button", "mt6 but jb-red initiate-pay btn-block radius aksrt-vip-submit", canPurchase ? (group.items[0].cta_label || actionLabel(action)) : (reason || "暂无可用支付方式"));
|
||||
submit.type = "button";
|
||||
submit.disabled = !canPurchase;
|
||||
submit.setAttribute("data-vip-submit", "");
|
||||
@@ -401,12 +434,10 @@
|
||||
}
|
||||
|
||||
function selectedMethod(root) {
|
||||
var fixed = root.querySelector("[data-aksrt-vip-method-fixed]");
|
||||
if (fixed && fixed.value) return fixed.value;
|
||||
var checked = root.querySelector('input[name="aksrt_vip_pay_method"]:checked');
|
||||
if (checked) return checked.value;
|
||||
var first = root.querySelector('input[name="aksrt_vip_pay_method"]');
|
||||
return first ? first.value : "balance";
|
||||
var hidden = root.querySelector('input[name="payment_method"]');
|
||||
if (hidden && hidden.value) return hidden.value;
|
||||
var first = root.querySelector('[data-for="payment_method"]');
|
||||
return first ? first.getAttribute("data-value") : "balance";
|
||||
}
|
||||
|
||||
function selectedPackage(root) {
|
||||
@@ -538,12 +569,18 @@
|
||||
function bindModalUi(root) {
|
||||
if (!root || root.dataset.aksrtVipBound === "1") return;
|
||||
root.dataset.aksrtVipBound = "1";
|
||||
root.addEventListener("change", function (event) {
|
||||
var input = event.target.closest ? event.target.closest('input[name="aksrt_vip_pay_method"]') : null;
|
||||
if (!input) return;
|
||||
applyVipMethodVisibility(input);
|
||||
});
|
||||
root.addEventListener("click", function (event) {
|
||||
var methodItem = event.target.closest ? event.target.closest('[data-for="payment_method"]') : null;
|
||||
if (methodItem) {
|
||||
var pane = methodItem.closest(".aksrt-vip-pane") || root;
|
||||
pane.querySelectorAll('[data-for="payment_method"]').forEach(function (el) {
|
||||
el.classList.toggle("active", el === methodItem);
|
||||
});
|
||||
var hidden = pane.querySelector('input[name="payment_method"]');
|
||||
if (hidden) hidden.value = methodItem.getAttribute("data-value") || "";
|
||||
applyVipMethodVisibility(pane);
|
||||
return;
|
||||
}
|
||||
var tab = event.target.closest("[data-vip-tab]");
|
||||
if (tab) {
|
||||
event.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user