diff --git a/components-diy/diy-card-show.vue b/components-diy/diy-card-show.vue index 90f1f01..e67c513 100644 --- a/components-diy/diy-card-show.vue +++ b/components-diy/diy-card-show.vue @@ -219,28 +219,10 @@ export default { return normalizeQrStyle(this.c.qrStyle); }, qrBlockStyle() { + // 2026-10-23 用户定稿: 外观衬底不设在块上(否则蓝底把「扫码查看完整名片」提示一起包住), + // 只保留微调位移; 衬底移到二维码图上(qrImgStyle), 紧贴码本身 const style = {}; - const theme = (this.card && this.card.theme_color) || CardTokens.color.primary; - if (this.qrStyle === 'card') { - style.background = '#ffffff'; - style.border = '2rpx solid #EEF0F3'; - style.borderRadius = '12rpx'; - style.padding = '10rpx'; - } else if (this.qrStyle === 'theme') { - style.background = theme; - style.borderRadius = '12rpx'; - style.padding = '10rpx'; - } else if (this.qrStyle === 'gradient') { - // 名片仅单主题色(无 gradient_end)时, themeGradient 返回纯色渐变(看不出渐变), - // 故用压暗一档的终止色保证「渐变圆角」始终可见明暗过渡 - const theme = (this.card && this.card.theme_color) || CardTokens.color.primary; - const end = (this.card && this.card.gradient_end) || darkenColor(theme, 0.18); - style.background = 'linear-gradient(135deg, ' + theme + ' 0%, ' + end + ' 100%)'; - style.borderRadius = '16rpx'; - style.padding = '6rpx'; - } - // plain 不进任何分支(无衬底, 即原图) - // 微调位移(qrOffsetX/Y): 与外观合并成同一段内联样式 + // 微调位移(qrOffsetX/Y) const t = qrTransform(this.c.qrOffsetX, this.c.qrOffsetY); if (t) style.transform = t; return this.$util.objToStyle(style); @@ -293,10 +275,31 @@ export default { return resolveQrSize(this.qrPos, this.c.qrSize); }, qrImgStyle() { - return this.$util.objToStyle({ + const style = { width: this.qrSide + 'rpx', height: this.qrSide + 'rpx', - }); + // 外观衬底只包二维码图(边距不撑大总尺寸), 提示文字在衬底外 + boxSizing: 'border-box', + }; + const theme = (this.card && this.card.theme_color) || CardTokens.color.primary; + if (this.qrStyle === 'card') { + style.background = '#ffffff'; + style.border = '2rpx solid #EEF0F3'; + style.borderRadius = '12rpx'; + style.padding = '10rpx'; + } else if (this.qrStyle === 'theme') { + style.background = theme; + style.borderRadius = '12rpx'; + style.padding = '10rpx'; + } else if (this.qrStyle === 'gradient') { + // 名片仅单主题色(无 gradient_end)时, 用压暗一档的终止色保证「渐变圆角」始终可见明暗过渡 + const end = (this.card && this.card.gradient_end) || darkenColor(theme, 0.18); + style.background = 'linear-gradient(135deg, ' + theme + ' 0%, ' + end + ' 100%)'; + style.borderRadius = '16rpx'; + style.padding = '6rpx'; + } + // plain 不进任何分支(无衬底, 即原图) + return this.$util.objToStyle(style); }, nameStyle() { return this.$util.objToStyle({ color: this.c.nameColor || CardTokens.color.text }); diff --git a/tests/diy-card-qr-style.test.js b/tests/diy-card-qr-style.test.js index dc1a6a4..32575b2 100644 --- a/tests/diy-card-qr-style.test.js +++ b/tests/diy-card-qr-style.test.js @@ -349,10 +349,13 @@ test('show: 二维码外观四档(plain 原图 / card 白卡描边 / theme 主 assert.match(showSrc, /if \(this\.qrStyle === 'card'\) \{\s+style\.background = '#ffffff';\s+style\.border = '2rpx solid #EEF0F3';\s+style\.borderRadius = '12rpx';\s+style\.padding = '10rpx';/); assert.match(showSrc, /else if \(this\.qrStyle === 'theme'\) \{\s+style\.background = theme;\s+style\.borderRadius = '12rpx';\s+style\.padding = '10rpx';/); // gradient 分支: 单主题色时也要可见明暗渐变(用 darkenColor 兜底终止色), 不能退化成纯色 - assert.match(showSrc, /else if \(this\.qrStyle === 'gradient'\) \{\s+const theme = \(this\.card && this\.card\.theme_color\) \|\| CardTokens\.color\.primary;\s+const end = \(this\.card && this\.card\.gradient_end\) \|\| darkenColor\(theme, 0\.18\);\s+style\.background = 'linear-gradient\(135deg, ' \+ theme \+ ' 0%, ' \+ end \+ ' 100%\)';\s+style\.borderRadius = '16rpx';\s+style\.padding = '6rpx';/); + // (2026-10-23 用户定稿: 外观分支移到 qrImgStyle, theme 在顶部声明一次) + assert.match(showSrc, /else if \(this\.qrStyle === 'gradient'\) \{\s+const end = \(this\.card && this\.card\.gradient_end\) \|\| darkenColor\(theme, 0\.18\);\s+style\.background = 'linear-gradient\(135deg, ' \+ theme \+ ' 0%, ' \+ end \+ ' 100%\)';\s+style\.borderRadius = '16rpx';\s+style\.padding = '6rpx';/); // plain 不进任何分支(无衬底, 即原图) assert.ok(!showSrc.includes("qrStyle === 'plain' ? style.background")); - // 四个位置档共用 qrBlockStyle(单字符串绑定) + // 衬底只包二维码图(qrImgStyle 绑在 image 上), 「扫码查看完整名片」tip 在衬底外(蓝底不包文字) + assert.equal((showSrc.match(/class="qr-img(-c)?" :style="qrImgStyle"/g) || []).length, 4, '四档 image 均绑 qrImgStyle'); + // 四个位置档共用 qrBlockStyle(单字符串绑定; 仅剩微调位移) assert.equal((showSrc.match(/:style="qrBlockStyle"/g) || []).length, 4); // 反例: uni-app 运行时静默丢弃 :style="[字符串, 字符串]" 数组绑定 // (2026-10-22 线上问题: 微调/外观在 C 端全部失效的根因), 禁止回归