refactor(revenue): drop standalone QR block and align promotion card with reference
The 推广收益 detail card no longer renders the QR code as its own row. The card becomes a fixed-label info list: 推广链接 [Url][复制链接][推广海报] / 佣金比例 / 累计佣金 / 返佣详解, mirroring the reference theme's 推广中心 card. - profile-revenue.php: QR row removed; poster button moved into the link row and gated server-side on the poster switch; copy label now 复制链接; 推广人数 row dropped; 返佣详解 heading reads the existing pay_rebate_text_details_title; dead $vip_ratios, aksrt-revenue-page class and data-min-amount removed - new affiliate-poster-modal.php: poster previews in a modal before download (reuses .uc-modal + single-render guard), since the QR now only exists inside the poster - credits.js: renderAffiliateQr and its call deleted, along with the dead [data-affiliate-payers] lookup and the inline ch-width hack; initAffiliatePoster builds the poster into the modal stage and reveals 保存海报 - PaymentRuntime: expose affiliate details_title - user-center.js: remove never-defined AKSRTRevenueCenterInit guards (2 sites) - CSS: revenue-earnings.css pruned to live rules plus the new link-row grid and poster stage styles; routes/user-center/revenue.css pruned to its only definitions; dead leaves routes/revenue.css and routes/commerce.css deleted and dequeued from the user-center part list - tests: referral-qr-contract test 2 rewritten for the QR-free card, link row and poster modal; post-visual-contract leaf list updated with regression guards qrcode.min.js stays enqueued — buildPosterCanvas still draws the QR inside the poster. Net -833 lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+38
-73
@@ -125,19 +125,12 @@
|
||||
function setFeedback(text, error) { if (feedback) { feedback.textContent = text; feedback.classList.toggle('is-error', !!error); } }
|
||||
api('/revenue/me').then(function (r) {
|
||||
if (!r.ok) { setFeedback((r.json && r.json.message) || '推广数据加载失败。', true); return; }
|
||||
var j = r.json || {}, stats = j.stats || {};
|
||||
var j = r.json || {};
|
||||
if (input) {
|
||||
input.value = j.url || '';
|
||||
/* Keep the complete ref URL readable on desktop; mobile CSS still caps it. */
|
||||
var linkLength = String(j.url || '').length;
|
||||
input.setAttribute('size', String(Math.max(28, Math.min(96, linkLength || 28))));
|
||||
input.style.width = Math.max(28, Math.min(96, linkLength || 28)) + 'ch';
|
||||
}
|
||||
if (copy) copy.disabled = !j.url;
|
||||
var ratio = root.querySelector('[data-affiliate-ratio]'); if (ratio) ratio.textContent = String(j.current_ratio || 0) + '%';
|
||||
var promoters = root.querySelector('[data-affiliate-promoters]'); if (promoters) promoters.textContent = String(stats.promoters || 0);
|
||||
var payers = root.querySelector('[data-affiliate-payers]'); if (payers) payers.textContent = String(stats.effective_payers || 0);
|
||||
renderAffiliateQr(root, j.url || '');
|
||||
initAffiliatePoster(root, j.url || '', j.poster || {}, j.site_name || document.title);
|
||||
}).catch(function () { setFeedback('推广数据加载失败。', true); });
|
||||
if (copy) copy.addEventListener('click', function () {
|
||||
@@ -148,78 +141,50 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ===== Referral QR code (bundled qrcode-generator, no CDN) =====
|
||||
function renderAffiliateQr(root, url) {
|
||||
var row = root.querySelector('[data-affiliate-qr-row]');
|
||||
var canvas = root.querySelector('[data-affiliate-qr]');
|
||||
if (!row || !canvas) return;
|
||||
if (!url || typeof window.qrcode !== 'function') {
|
||||
row.hidden = true;
|
||||
return;
|
||||
}
|
||||
var feedback = root.querySelector('[data-affiliate-qr-feedback]');
|
||||
function setQrFeedback(text, error) { if (feedback) { feedback.textContent = text; feedback.classList.toggle('is-error', !!error); } }
|
||||
try {
|
||||
var qr = window.qrcode(0, 'M');
|
||||
qr.addData(url);
|
||||
qr.make();
|
||||
var count = qr.getModuleCount();
|
||||
var cell = 4, margin = 4;
|
||||
var size = (count + margin * 2) * cell;
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
ctx.fillStyle = '#0f172a';
|
||||
for (var r = 0; r < count; r++) {
|
||||
for (var c = 0; c < count; c++) {
|
||||
if (qr.isDark(r, c)) {
|
||||
ctx.fillRect((c + margin) * cell, (r + margin) * cell, cell, cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
row.hidden = true;
|
||||
return;
|
||||
}
|
||||
var download = root.querySelector('[data-affiliate-qr-download]');
|
||||
if (download) download.addEventListener('click', function () {
|
||||
try {
|
||||
var link = document.createElement('a');
|
||||
link.download = 'referral-qr.png';
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
setQrFeedback('二维码已下载。');
|
||||
} catch (err) {
|
||||
setQrFeedback('二维码下载失败,请截图保存。', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ===== Referral poster (canvas: hero image + copy + QR + link) =====
|
||||
// ===== Referral poster (canvas preview modal: hero image + copy + QR + link) =====
|
||||
function initAffiliatePoster(root, url, poster, siteName) {
|
||||
var button = root.querySelector('[data-affiliate-poster]');
|
||||
if (!button) return;
|
||||
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]');
|
||||
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 canvas = null;
|
||||
if (download) {
|
||||
download.addEventListener('click', function () {
|
||||
if (!canvas) return;
|
||||
try {
|
||||
var link = document.createElement('a');
|
||||
link.download = 'referral-poster.png';
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
} catch (err) {
|
||||
/* Canvas is same-origin generated; download can only fail if the browser blocks it. */
|
||||
}
|
||||
});
|
||||
}
|
||||
button.addEventListener('click', function () {
|
||||
var feedback = root.querySelector('[data-affiliate-qr-feedback]');
|
||||
function setPosterFeedback(text, error) { if (feedback) { feedback.textContent = text; feedback.classList.toggle('is-error', !!error); } }
|
||||
if (typeof window.qrcode !== 'function') { setPosterFeedback('二维码组件未加载。', true); return; }
|
||||
if (typeof window.qrcode !== 'function') {
|
||||
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '二维码组件未加载。' + '</p>'; }
|
||||
openModal(modal);
|
||||
return;
|
||||
}
|
||||
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '正在生成海报…' + '</p>'; }
|
||||
if (download) download.hidden = true;
|
||||
openModal(modal);
|
||||
button.disabled = true;
|
||||
buildPosterCanvas(url, poster, siteName).then(function (canvas) {
|
||||
var link = document.createElement('a');
|
||||
link.download = 'referral-poster.png';
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
setPosterFeedback('推广海报已生成并下载。');
|
||||
buildPosterCanvas(url, poster, siteName).then(function (built) {
|
||||
canvas = built;
|
||||
if (stage) { stage.innerHTML = ''; stage.appendChild(built); }
|
||||
if (download) download.hidden = false;
|
||||
}).catch(function () {
|
||||
setPosterFeedback('海报生成失败,请重试。', true);
|
||||
if (stage) { stage.innerHTML = '<p class="muted-2-color em09">' + '海报生成失败,请重试。' + '</p>'; }
|
||||
}).finally(function () {
|
||||
button.disabled = false;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user