chore:二维码外观

This commit is contained in:
2026-10-24 08:39:32 +08:00
parent c9d77e901d
commit ff530cd6a2
2 changed files with 31 additions and 25 deletions

View File

@@ -219,28 +219,10 @@ export default {
return normalizeQrStyle(this.c.qrStyle); return normalizeQrStyle(this.c.qrStyle);
}, },
qrBlockStyle() { qrBlockStyle() {
// 2026-10-23 用户定稿: 外观衬底不设在块上(否则蓝底把「扫码查看完整名片」提示一起包住),
// 只保留微调位移; 衬底移到二维码图上(qrImgStyle), 紧贴码本身
const style = {}; const style = {};
const theme = (this.card && this.card.theme_color) || CardTokens.color.primary; // 微调位移(qrOffsetX/Y)
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): 与外观合并成同一段内联样式
const t = qrTransform(this.c.qrOffsetX, this.c.qrOffsetY); const t = qrTransform(this.c.qrOffsetX, this.c.qrOffsetY);
if (t) style.transform = t; if (t) style.transform = t;
return this.$util.objToStyle(style); return this.$util.objToStyle(style);
@@ -293,10 +275,31 @@ export default {
return resolveQrSize(this.qrPos, this.c.qrSize); return resolveQrSize(this.qrPos, this.c.qrSize);
}, },
qrImgStyle() { qrImgStyle() {
return this.$util.objToStyle({ const style = {
width: this.qrSide + 'rpx', width: this.qrSide + 'rpx',
height: 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() { nameStyle() {
return this.$util.objToStyle({ color: this.c.nameColor || CardTokens.color.text }); return this.$util.objToStyle({ color: this.c.nameColor || CardTokens.color.text });

View File

@@ -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, /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';/); assert.match(showSrc, /else if \(this\.qrStyle === 'theme'\) \{\s+style\.background = theme;\s+style\.borderRadius = '12rpx';\s+style\.padding = '10rpx';/);
// gradient 分支: 单主题色时也要可见明暗渐变(用 darkenColor 兜底终止色), 不能退化成纯色 // 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 不进任何分支(无衬底, 即原图) // plain 不进任何分支(无衬底, 即原图)
assert.ok(!showSrc.includes("qrStyle === 'plain' ? style.background")); 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); assert.equal((showSrc.match(/:style="qrBlockStyle"/g) || []).length, 4);
// 反例: uni-app 运行时静默丢弃 :style="[字符串, 字符串]" 数组绑定 // 反例: uni-app 运行时静默丢弃 :style="[字符串, 字符串]" 数组绑定
// (2026-10-22 线上问题: 微调/外观在 C 端全部失效的根因), 禁止回归 // (2026-10-22 线上问题: 微调/外观在 C 端全部失效的根因), 禁止回归