fix(revenue): match reference poster modal UI 1:1

The 推广海报 modal on the revenue page used a bespoke .uc-modal card —
white panel, 12px radius, heavy shadow, title bar, corner × button and a
full-width 保存海报 button — plus a light-gray plate with its own
border-radius around the poster canvas. None of that exists in the
reference theme, so the popup read as bordered and off-spec.

Rebuild the modal on the reference poster-share structure: a borderless
360px .modal-dialog.poster-share centred by .modal.flex.jc, a
.loading-mask overlay while the canvas renders, and the download/close
buttons moved onto a .abs-center.hover-show-con layer that only fades in
on hover. initAffiliatePoster() now drives Bootstrap 3 modal semantics
(.in toggle, .modal-backdrop, body.modal-open, ESC and backdrop-click to
close), mirroring the existing openChargeModal/closeChargeModal pair, and
animates .modal-content from the 220px placeholder to the poster's real
height before clearing the inline styles.

No CSS added — every rule the reference modal needs was already ported.
Drop the now-dead .uc-affiliate-poster rules; the shared .uc-modal shell
and openModal/closeModal stay for the withdraw and transfer modals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-21 16:02:41 +08:00
1 parent a120f61e13
commit de0e5cd481
4 files changed
+135 -30

No files matched your search

+82 -12
View File
@@ -150,19 +150,62 @@
});
}
// ===== Referral poster (canvas preview modal: hero image + copy + QR + link) =====
// ===== Referral poster =====
// 弹窗形态 1:1 复刻参考主题 poster-share.js:Bootstrap 语义(.in 显隐 +
// .modal-backdrop + body.modal-open + ESC),与下方充值弹窗同构,不复依赖
// jQuery/Bootstrap 运行时。壳上带 .flex.jc,故打开态用 flex 而非 block。
function initAffiliatePoster(root, url, poster, siteName) {
var button = root.querySelector('[data-affiliate-poster]');
var modal = document.querySelector('[data-aksrt-affiliate-poster-modal]');
var stage = document.querySelector('[data-affiliate-poster-stage]');
var download = document.querySelector('[data-affiliate-poster-download]');
var stage = modal ? modal.querySelector('[data-affiliate-poster-stage]') : null;
var loading = modal ? modal.querySelector('[data-affiliate-poster-loading]') : null;
var content = modal ? modal.querySelector('.modal-content') : null;
var download = modal ? modal.querySelector('[data-affiliate-poster-download]') : null;
if (!button || !modal) return;
if (!url || !poster || poster.enabled !== true) return;
button.hidden = false;
[].forEach.call(modal.querySelectorAll('[data-affiliate-poster-close]'), function (closer) {
closer.addEventListener('click', function () { closeModal(modal); });
});
var backdrop = null;
var canvas = null;
function openPosterModal() {
if (modal.classList.contains('in')) return;
modal.style.display = 'flex';
void modal.offsetWidth; // 强制 reflow,让 .fade 过渡从 scale(0.9) 起手
modal.classList.add('in');
modal.setAttribute('aria-hidden', 'false');
if (!backdrop) {
backdrop = document.createElement('div');
backdrop.className = 'modal-backdrop fade in';
backdrop.setAttribute('data-affiliate-poster-backdrop', '1');
document.body.appendChild(backdrop);
}
document.body.classList.add('modal-open');
}
function closePosterModal() {
if (!modal.classList.contains('in')) return;
modal.classList.remove('in');
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('modal-open');
if (backdrop && backdrop.parentNode) backdrop.parentNode.removeChild(backdrop);
backdrop = null;
// 等过渡结束再撤 display,复刻 Bootstrap 的 fade-out 收尾
window.setTimeout(function () {
if (!modal.classList.contains('in')) modal.style.display = '';
}, 300);
}
modal.addEventListener('click', function (event) {
// 点遮罩层(.modal 自身)或关闭按钮(data-dismiss="modal")
if (event.target === modal || (event.target.closest && event.target.closest('[data-dismiss="modal"]'))) {
closePosterModal();
}
});
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape' && modal.classList.contains('in')) closePosterModal();
});
if (download) {
download.addEventListener('click', function () {
if (!canvas) return;
@@ -178,20 +221,47 @@
}
});
}
button.addEventListener('click', function () {
if (typeof window.qrcode !== 'function') {
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '二维码组件未加载。' + '</p>'; }
openModal(modal);
openPosterModal();
return;
}
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '正在生成海报…' + '</p>'; }
if (download) download.hidden = true;
openModal(modal);
if (stage) { stage.innerHTML = ''; stage.classList.remove('loaded'); }
if (loading) loading.style.display = '';
if (download) download.classList.add('hide');
openPosterModal();
button.disabled = true;
buildPosterCanvas(url, poster, siteName).then(function (built) {
canvas = built;
if (stage) { stage.innerHTML = ''; stage.appendChild(built); }
if (download) download.hidden = false;
if (!stage) return;
// 参考主题:img.loaded-img 直接进 .poster-imgbox,遮罩淡出,
// 内容块高度从 220px 过渡到海报实际高度后清掉内联样式。
var img = document.createElement('img');
img.src = canvas.toDataURL('image/png');
img.alt = '推广海报';
img.className = 'loaded-img';
// 参考主题按 0.7 比例预设尺寸;.poster-imgbox > img 的 max-width:360px
// 会在窄屏把它压回弹窗宽度,height:100% 让 offsetHeight 反映真实渲染高度。
img.width = 768 * 0.7;
img.height = 1168 * 0.7;
stage.appendChild(img);
stage.classList.add('loaded');
if (download) {
download.href = img.src;
download.classList.remove('hide');
}
if (loading) loading.style.display = 'none';
if (content) {
content.style.height = stage.offsetHeight + 'px';
content.style.transition = '.2s';
window.setTimeout(function () {
content.style.height = '';
content.style.overflow = '';
content.style.transition = '';
}, 200);
}
}).catch(function () {
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '海报生成失败,请重试。' + '</p>'; }
}).finally(function () {