chore:二维码位置和后台同步
This commit is contained in:
@@ -30,7 +30,8 @@
|
||||
<text class="card-name" :style="nameStyle">{{ card.name || '未命名名片' }}</text>
|
||||
<text v-if="jobLine" class="card-job" :style="subStyle">{{ jobLine }}</text>
|
||||
</view>
|
||||
<view v-if="showQrBlock && card.qr_url" class="card-qr" hover-class="btn-press" @tap.stop="openCardShare">
|
||||
<!-- 头部右侧档 -->
|
||||
<view v-if="showQrHead" class="card-qr" :style="qrShiftStyle" hover-class="btn-press" @tap.stop="openCardShare">
|
||||
<image class="qr-img" :style="qrImgStyle" :src="$util.img(card.qr_url)" mode="aspectFit" />
|
||||
<text class="qr-tip" :style="subStyle">{{ qrTipText }}</text>
|
||||
</view>
|
||||
@@ -51,6 +52,18 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 资料行下方档(默认): 大码居中, 资料行随之下移 -->
|
||||
<view v-if="showQrRows" class="qr-center" :style="qrShiftStyle" hover-class="btn-press" @tap.stop="openCardShare">
|
||||
<image class="qr-img-c" :style="qrImgStyle" :src="$util.img(card.qr_url)" mode="aspectFit" />
|
||||
<text class="qr-tip-c" :style="subStyle">{{ qrTipText }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 右上角浮层档: 白底描边小卡浮在名片右上角, 点击弹分享抽屉 -->
|
||||
<view v-if="showQrCorner" class="card-qr-corner" :style="qrShiftStyle" hover-class="btn-press" @tap.stop="openCardShare">
|
||||
<image class="qr-img-c" :style="qrImgStyle" :src="$util.img(card.qr_url)" mode="aspectFit" />
|
||||
<text class="qr-tip-corner" :style="subStyle">{{ qrTipText }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 快捷操作(面板「显示快捷操作」可关; 服务端按资料派生, 首个主动作填充) -->
|
||||
<view v-if="showActsBlock && acts.length" class="card-acts">
|
||||
<view v-for="(act, i) in acts" :key="i" class="act-chip"
|
||||
@@ -61,6 +74,12 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 主按钮上方档: 大码居中卡于白卡与发名片按钮之间 -->
|
||||
<view v-if="showQrBottom" class="qr-center qr-center-bottom" :style="qrShiftStyle" hover-class="btn-press" @tap.stop="openCardShare">
|
||||
<image class="qr-img-c" :style="qrImgStyle" :src="$util.img(card.qr_url)" mode="aspectFit" />
|
||||
<text class="qr-tip-c" :style="subStyle">{{ qrTipText }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 发名片: 卡片外下方胶囊(详情页 send-bar 同款观感, 主题渐变色) -->
|
||||
<view class="show-send" :style="sendBtnStyle" hover-class="btn-press" @tap="onSend(card)">
|
||||
<text class="show-send-text">发名片</text>
|
||||
@@ -102,7 +121,7 @@
|
||||
// 图标资料行 + 卡外「发名片」胶囊。面板仅颜色/底色/圆角/阴影/行数继续生效。
|
||||
import {
|
||||
CardTokens, px2rpx, num, flagOn, initialOf, avatarBg, themeGradient, visibleRows, rowIconFor, rowActOf,
|
||||
resolveQrSize,
|
||||
resolveQrSize, normalizeQrPosition, qrTransform,
|
||||
} from './diy-card-common.js';
|
||||
|
||||
export default {
|
||||
@@ -147,6 +166,24 @@ export default {
|
||||
showQrBlock() {
|
||||
return flagOn(this.c.showQr, true);
|
||||
},
|
||||
/** 二维码位置(四档, 与面板下拉/mini 基件同口径): rows 资料行下方 / head 头部右侧 /
|
||||
* corner 右上角浮层 / bottom 主按钮上方; 未配置回落 rows(面板默认档) */
|
||||
qrPos() {
|
||||
return normalizeQrPosition(this.c.qrPosition);
|
||||
},
|
||||
/** 位置分档显隐(共用 showQrBlock + qr_url 前置) */
|
||||
showQrBase() {
|
||||
return this.showQrBlock && !!(this.card && this.card.qr_url);
|
||||
},
|
||||
showQrHead() { return this.showQrBase && this.qrPos === 'head'; },
|
||||
showQrRows() { return this.showQrBase && this.qrPos === 'rows'; },
|
||||
showQrCorner() { return this.showQrBase && this.qrPos === 'corner'; },
|
||||
showQrBottom() { return this.showQrBase && this.qrPos === 'bottom'; },
|
||||
/** 二维码微调(qrOffsetX/Y, 任一轴非零才输出 transform) */
|
||||
qrShiftStyle() {
|
||||
const t = qrTransform(this.c.qrOffsetX, this.c.qrOffsetY);
|
||||
return t ? this.$util.objToStyle({ transform: t }) : '';
|
||||
},
|
||||
/** 二维码提示文字: 面板 qrTip, 未配置回落「扫码查看完整名片」 */
|
||||
qrTipText() {
|
||||
return this.c.qrTip || '扫码查看完整名片';
|
||||
@@ -195,11 +232,12 @@ export default {
|
||||
const card = this.card || {};
|
||||
return card.job_title || card.company || card.card_title || '';
|
||||
},
|
||||
/** 二维码边长: 面板 qrSize > 0 用自定义(px), 0/空 = 「按位自动」走头部右侧档(120rpx)。
|
||||
/** 二维码边长: 面板 qrSize > 0 用自定义(px), 0/空 = 「按位自动」按位置档位取值
|
||||
* (rows/bottom 180rpx, head/corner 120rpx, 见 common.QR_SIZES)。
|
||||
* 之前用 num(qrSize, 48) 兜底 —— 面板默认 0 是合法数字不触发默认值,
|
||||
* 算出 0rpx 宽高, 二维码图被渲染成 0 尺寸「看不见」 */
|
||||
qrSide() {
|
||||
return resolveQrSize('head', this.c.qrSize);
|
||||
return resolveQrSize(this.qrPos, this.c.qrSize);
|
||||
},
|
||||
qrImgStyle() {
|
||||
return this.$util.objToStyle({
|
||||
@@ -574,6 +612,46 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 右上角浮层档: 白底描边小卡浮在名片右上角(z-index 压过头部信息) */
|
||||
.card-qr-corner {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 20rpx;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 10rpx;
|
||||
background-color: #ffffff;
|
||||
border: 2rpx solid #EEF0F3;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(15, 23, 42, 0.10);
|
||||
|
||||
.qr-tip-corner {
|
||||
font-size: 20rpx;
|
||||
margin-top: 4rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 资料行下方 / 主按钮上方档: 大码居中(边长走 qrImgStyle 内联) */
|
||||
.qr-center {
|
||||
margin-top: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.qr-tip-c {
|
||||
font-size: 22rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
/* 卡外(主按钮上方): 与上下元素拉开间距 */
|
||||
&.qr-center-bottom {
|
||||
margin: 32rpx 24rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 发名片: 卡片外下方胶囊(背景色由 sendBtnStyle 内联) */
|
||||
|
||||
@@ -196,12 +196,29 @@ test('show: 快捷操作开关(面板「显示快捷操作」, 默认显示, 关
|
||||
assert.match(showSrc, /@tap\.stop="doAct\(act\)"/);
|
||||
});
|
||||
|
||||
test('show: 二维码位置四档(与面板下拉/mini 基件同口径, 未配置回落 rows)', () => {
|
||||
assert.match(showSrc, /qrPos\(\)\s*\{\s*return normalizeQrPosition\(this\.c\.qrPosition\)/);
|
||||
// 四档各自的条件渲染块
|
||||
assert.match(showSrc, /showQrHead\(\)\s*\{\s*return this\.showQrBase && this\.qrPos === 'head';\s*\}/);
|
||||
assert.match(showSrc, /showQrRows\(\)\s*\{\s*return this\.showQrBase && this\.qrPos === 'rows';\s*\}/);
|
||||
assert.match(showSrc, /showQrCorner\(\)\s*\{\s*return this\.showQrBase && this\.qrPos === 'corner';\s*\}/);
|
||||
assert.match(showSrc, /showQrBottom\(\)\s*\{\s*return this\.showQrBase && this\.qrPos === 'bottom';\s*\}/);
|
||||
// 模板四个位置都有落点(头部/资料行下/浮层/主按钮上方)
|
||||
assert.match(showSrc, /v-if="showQrHead" class="card-qr"/);
|
||||
assert.match(showSrc, /v-if="showQrRows" class="qr-center"/);
|
||||
assert.match(showSrc, /v-if="showQrCorner" class="card-qr-corner"/);
|
||||
assert.match(showSrc, /v-if="showQrBottom" class="qr-center qr-center-bottom"/);
|
||||
// 微调位移(qrOffsetX/Y → transform)
|
||||
assert.match(showSrc, /qrTransform\(this\.c\.qrOffsetX,\s*this\.c\.qrOffsetY\)/);
|
||||
});
|
||||
|
||||
test('show: 自绘版式自带小二维码(开关可关 + 点击进详情, 尺寸/提示文字面板可调)', () => {
|
||||
assert.match(showSrc, /class="card-qr"/);
|
||||
assert.match(showSrc, /\$util\.img\(card\.qr_url\)/);
|
||||
// 二维码块受面板「显示二维码」开关控制(与头像/资料行/快捷操作同口径: flagOn 默认显示)
|
||||
assert.match(showSrc, /showQrBlock\(\)\s*\{\s*return flagOn\(this\.c\.showQr,\s*true\)/);
|
||||
assert.match(showSrc, /v-if="showQrBlock && card\.qr_url" class="card-qr"/);
|
||||
// 开关 + 位置统一收敛在 showQrBase / showQrHead 等分档计算属性里(模板只消费分档结果)
|
||||
assert.match(showSrc, /showQrBase\(\)\s*\{\s*return this\.showQrBlock && !!\(this\.card && this\.card\.qr_url\)/);
|
||||
// 提示文字消费面板 qrTip, 未配置回落「扫码查看完整名片」(与 mini 基件同口径)
|
||||
assert.match(showSrc, /qrTipText\(\)\s*\{\s*return this\.c\.qrTip \|\| '扫码查看完整名片';/);
|
||||
// 点二维码弹「分享名片」抽屉(复刻 detail.vue: 码 + 链接 + 复制链接/浏览器分享/保存二维码)
|
||||
@@ -211,10 +228,10 @@ test('show: 自绘版式自带小二维码(开关可关 + 点击进详情, 尺
|
||||
assert.match(showSrc, /<view class="ss-title">分享名片<\/view>/);
|
||||
assert.match(showSrc, /客户打开链接即可查看名片并留言留资/);
|
||||
assert.match(showSrc, /copyCardLink\(\)\s*\{\s*const url = \(this\.card && this\.card\.wap_url\) \|\| '';/);
|
||||
// 尺寸走 resolveQrSize: 面板 qrSize>0 用自定义, 0/空 = 自动档(head 120rpx)。
|
||||
// 尺寸走 resolveQrSize: 面板 qrSize>0 用自定义, 0/空 = 按位置档位自动(rows/bottom 180, head/corner 120)。
|
||||
// 反例形态: 不允许 num(qrSize, 48) 兜底 —— 面板默认 0 是合法数字, 会算出 0rpx 宽高,
|
||||
// 二维码图渲染成 0 尺寸「看不见」(2026-10-21 线上问题)
|
||||
assert.match(showSrc, /qrSide\(\)\s*\{\s*return resolveQrSize\('head',\s*this\.c\.qrSize\)/);
|
||||
assert.match(showSrc, /qrSide\(\)\s*\{\s*return resolveQrSize\(this\.qrPos,\s*this\.c\.qrSize\)/);
|
||||
assert.ok(!showSrc.includes("num(this.c.qrSize"));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user