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:
kate522andClaude Fable 5 committed 2026-09-27 21:42:57 +08:00
1 parent 8d16ce6e02
commit 7761435a81
12 files changed
+136 -933

No files matched your search

@@ -20,21 +20,37 @@ test('QR generator is bundled locally; no external QR CDN in front-end sources',
assert.doesNotMatch(sources, /cdnjs\.cloudflare\.com[^"']*qrcode|cdn\.jsdelivr\.net[^"']*qrcode|unpkg\.com[^"']*qrcode/)
})
test('revenue page renders the QR row and credits.js draws + downloads it', () => {
test('revenue detail card is a four-row info list with no standalone QR block', () => {
const template = read('inc', 'helpers', 'user-center-renderers', 'profile-revenue.php')
assert.match(template, /data-affiliate-qr-row/)
assert.match(template, /data-affiliate-qr(?!-)/)
assert.match(template, /data-affiliate-qr-download/)
// 二维码不再作为独立行:整行 markup 已删除。
assert.doesNotMatch(template, /data-affiliate-qr-row/)
assert.doesNotMatch(template, /data-affiliate-qr(?!-)/)
assert.doesNotMatch(template, /data-affiliate-qr-download/)
assert.doesNotMatch(template, /data-affiliate-qr-feedback/)
assert.doesNotMatch(template, /<canvas/)
// 推广海报按钮并入推广链接行([Url][复制链接][推广海报])。
assert.match(template, /uc-revenue-summary-row--link/)
assert.match(template, /data-affiliate-link/)
assert.match(template, /data-affiliate-copy/)
assert.match(template, /data-affiliate-poster/)
assert.match(template, /data-affiliate-feedback/)
// 四行固定标签:推广链接 / 佣金比例 / 累计佣金 / 返佣详解。
for (const label of ['推广链接', '佣金比例', '累计佣金']) {
assert.match(template, new RegExp('<span><\\?php [a-z_]+\\([^)]*' + label), 'detail row label ' + label)
}
// 返佣详解标题走可配置字段,不再硬编码。
assert.match(template, /esc_html\(\$details_title\)/)
const script = read('assets', 'js', 'credits.js')
assert.match(script, /renderAffiliateQr\(root, j\.url \|\| ''\)/)
// 库缺失时整行隐藏,不抛错。
assert.match(script, /typeof window\.qrcode !== 'function'/)
assert.match(script, /row\.hidden = true/)
// Canvas 绘制(isDark 逐模块填充)+ PNG 下载。
assert.match(script, /qr\.isDark\(r, c\)/)
assert.match(script, /canvas\.toDataURL\('image\/png'\)/)
// 独立二维码绘制函数已删除;window.qrcode 仅供海报使用。
assert.doesNotMatch(script, /function renderAffiliateQr/)
assert.doesNotMatch(script, /renderAffiliateQr\(/)
assert.doesNotMatch(script, /data-affiliate-qr/)
// 海报弹窗:舞台 + 保存按钮 + 复用 openModal/closeModal。
assert.match(script, /data-affiliate-poster-stage/)
assert.match(script, /data-affiliate-poster-download/)
assert.match(script, /openModal\(modal\)/)
assert.match(script, /link\.download = 'referral-poster\.png'/)
})
test('poster canvas is built from admin-configured copy and gated on the poster switch', () => {