|
|
|
|
@@ -30,14 +30,14 @@
|
|
|
|
|
<text class="card-name" :style="nameStyle">{{ card.name || '未命名名片' }}</text>
|
|
|
|
|
<text v-if="jobLine" class="card-job" :style="subStyle">{{ jobLine }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-if="card.qr_url" class="card-qr" hover-class="btn-press" @tap.stop="goDetail(card)">
|
|
|
|
|
<view v-if="showQrBlock && card.qr_url" class="card-qr" 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">预览名片</text>
|
|
|
|
|
<text class="qr-tip" :style="subStyle">{{ qrTipText }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 资料行(有字形字段显图标, 无字形退化为文字标签; href 派生点击动作) -->
|
|
|
|
|
<view v-if="shownRows.length" class="card-rows">
|
|
|
|
|
<!-- 资料行(面板「显示资料行」可关; 有字形字段显图标, 无字形退化为文字标签; href 派生点击动作) -->
|
|
|
|
|
<view v-if="showRowsBlock && shownRows.length" class="card-rows">
|
|
|
|
|
<view v-for="(row, i) in shownRows" :key="i" class="card-row"
|
|
|
|
|
:class="{ 'row-tappable': rowTapable(row) }"
|
|
|
|
|
:hover-class="rowTapable(row) ? 'btn-press' : 'none'"
|
|
|
|
|
@@ -50,6 +50,15 @@
|
|
|
|
|
<text class="toggle-text" :style="themeTextStyle">{{ expanded ? '收起资料' : '展开全部资料(' + hiddenCount + ')' }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 快捷操作(面板「显示快捷操作」可关; 服务端按资料派生, 首个主动作填充) -->
|
|
|
|
|
<view v-if="showActsBlock && acts.length" class="card-acts">
|
|
|
|
|
<view v-for="(act, i) in acts" :key="i" class="act-chip"
|
|
|
|
|
:style="i === 0 ? actPrimaryStyle : actGhostStyle"
|
|
|
|
|
hover-class="btn-press" @tap.stop="doAct(act)">
|
|
|
|
|
<text class="act-text" :style="i === 0 ? actPrimaryTextStyle : actGhostTextStyle">{{ act.label }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 发名片: 卡片外下方胶囊(详情页 send-bar 同款观感, 主题渐变色) -->
|
|
|
|
|
@@ -57,6 +66,32 @@
|
|
|
|
|
<text class="show-send-text">发名片</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 分享名片抽屉: 点二维码弹出(pages_tool/card/detail.vue 同款版式/文案) -->
|
|
|
|
|
<view class="cs-mask" v-if="showShare" @tap="closeShare"></view>
|
|
|
|
|
<view class="cs-sheet" :class="{ 'cs-sheet-show': showShare }">
|
|
|
|
|
<view class="ss-bar"></view>
|
|
|
|
|
<view class="ss-title">分享名片</view>
|
|
|
|
|
<view class="ss-sub">客户打开链接即可查看名片并留言留资</view>
|
|
|
|
|
<view class="ss-qr-box">
|
|
|
|
|
<image v-if="card && card.qr_url" :src="$util.img(card.qr_url)" class="ss-qr" mode="widthFix" show-menu-by-longpress="true" />
|
|
|
|
|
</view>
|
|
|
|
|
<view class="ss-link">{{ (card && card.wap_url) || '' }}</view>
|
|
|
|
|
<view class="ss-btns">
|
|
|
|
|
<view class="ss-btn ss-btn-main" :style="shareBtnStyle" @tap="copyCardLink">复制链接</view>
|
|
|
|
|
<!-- #ifdef H5 -->
|
|
|
|
|
<view class="ss-btn" @tap="h5CardShare">浏览器分享</view>
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
<!-- #ifdef MP-WEIXIN || MP-HARMONY -->
|
|
|
|
|
<view class="ss-btn" @tap="saveCardQr">保存二维码</view>
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
</view>
|
|
|
|
|
<view class="ss-tip">
|
|
|
|
|
<!-- #ifdef MP-WEIXIN -->长按二维码也可保存到相册<!-- #endif -->
|
|
|
|
|
<!-- #ifdef H5 -->长按二维码可保存到相册<!-- #endif -->
|
|
|
|
|
<!-- #ifdef MP-HARMONY -->点击「保存二维码」存入相册<!-- #endif -->
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@@ -67,6 +102,7 @@
|
|
|
|
|
// 图标资料行 + 卡外「发名片」胶囊。面板仅颜色/底色/圆角/阴影/行数继续生效。
|
|
|
|
|
import {
|
|
|
|
|
CardTokens, px2rpx, num, flagOn, initialOf, avatarBg, themeGradient, visibleRows, rowIconFor, rowActOf,
|
|
|
|
|
resolveQrSize,
|
|
|
|
|
} from './diy-card-common.js';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
@@ -79,6 +115,7 @@ export default {
|
|
|
|
|
card: null,
|
|
|
|
|
loading: false,
|
|
|
|
|
expanded: false,
|
|
|
|
|
showShare: false,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
@@ -102,6 +139,54 @@ export default {
|
|
|
|
|
showAvatarBlock() {
|
|
|
|
|
return flagOn(this.c.showAvatar, true);
|
|
|
|
|
},
|
|
|
|
|
/** 资料行总开关: 面板「显示资料行」(历史配置无此字段默认显示; 关后整块隐藏) */
|
|
|
|
|
showRowsBlock() {
|
|
|
|
|
return flagOn(this.c.showRows, true);
|
|
|
|
|
},
|
|
|
|
|
/** 二维码开关: 面板「显示二维码」(历史配置无此字段默认显示; 关后头部只留姓名/职位) */
|
|
|
|
|
showQrBlock() {
|
|
|
|
|
return flagOn(this.c.showQr, true);
|
|
|
|
|
},
|
|
|
|
|
/** 二维码提示文字: 面板 qrTip, 未配置回落「扫码查看完整名片」 */
|
|
|
|
|
qrTipText() {
|
|
|
|
|
return this.c.qrTip || '扫码查看完整名片';
|
|
|
|
|
},
|
|
|
|
|
/** 分享抽屉主按钮: 主题色(禁 CSS 变量, 小程序端内联具体值) */
|
|
|
|
|
shareBtnStyle() {
|
|
|
|
|
const theme = (this.card && this.card.theme_color) || CardTokens.color.primary;
|
|
|
|
|
return this.$util.objToStyle({
|
|
|
|
|
background: theme,
|
|
|
|
|
border: '2rpx solid ' + theme,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/** 快捷操作开关: 面板「显示快捷操作」(历史配置无此字段默认显示; 关后芯片整块隐藏) */
|
|
|
|
|
showActsBlock() {
|
|
|
|
|
return flagOn(this.c.showQuick, true);
|
|
|
|
|
},
|
|
|
|
|
/** 快捷操作芯片: 服务端按名片实际资料派生(首个为主动作, 填充样式) */
|
|
|
|
|
acts() {
|
|
|
|
|
return this.card && Array.isArray(this.card.acts) ? this.card.acts : [];
|
|
|
|
|
},
|
|
|
|
|
actPrimaryStyle() {
|
|
|
|
|
const theme = (this.card && this.card.theme_color) || CardTokens.color.primary;
|
|
|
|
|
return this.$util.objToStyle({
|
|
|
|
|
background: theme,
|
|
|
|
|
border: '2rpx solid ' + theme,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
actGhostStyle() {
|
|
|
|
|
const theme = (this.card && this.card.theme_color) || CardTokens.color.primary;
|
|
|
|
|
return this.$util.objToStyle({
|
|
|
|
|
background: 'transparent',
|
|
|
|
|
border: '2rpx solid ' + theme,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
actPrimaryTextStyle() {
|
|
|
|
|
return this.$util.objToStyle({ color: '#FFFFFF' });
|
|
|
|
|
},
|
|
|
|
|
actGhostTextStyle() {
|
|
|
|
|
return this.$util.objToStyle({ color: (this.card && this.card.theme_color) || CardTokens.color.primary });
|
|
|
|
|
},
|
|
|
|
|
avatarStyle() {
|
|
|
|
|
return this.$util.objToStyle({ background: avatarBg(this.card) });
|
|
|
|
|
},
|
|
|
|
|
@@ -110,9 +195,11 @@ export default {
|
|
|
|
|
const card = this.card || {};
|
|
|
|
|
return card.job_title || card.company || card.card_title || '';
|
|
|
|
|
},
|
|
|
|
|
/** 二维码边长: 面板自定义 qrSize(px) > 0 时生效, 否则固定 48px */
|
|
|
|
|
/** 二维码边长: 面板 qrSize > 0 用自定义(px), 0/空 = 「按位自动」走头部右侧档(120rpx)。
|
|
|
|
|
* 之前用 num(qrSize, 48) 兜底 —— 面板默认 0 是合法数字不触发默认值,
|
|
|
|
|
* 算出 0rpx 宽高, 二维码图被渲染成 0 尺寸「看不见」 */
|
|
|
|
|
qrSide() {
|
|
|
|
|
return px2rpx(num(this.c.qrSize, 48));
|
|
|
|
|
return resolveQrSize('head', this.c.qrSize);
|
|
|
|
|
},
|
|
|
|
|
qrImgStyle() {
|
|
|
|
|
return this.$util.objToStyle({
|
|
|
|
|
@@ -233,6 +320,59 @@ export default {
|
|
|
|
|
if (!card || !card.card_id) return;
|
|
|
|
|
this.$util.redirectTo('/pages_tool/card/detail', { card_id: card.card_id });
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/* ---------- 分享名片抽屉(点二维码弹出, 版式/文案对齐 pages_tool/card/detail.vue) ---------- */
|
|
|
|
|
openCardShare() {
|
|
|
|
|
this.showShare = true;
|
|
|
|
|
},
|
|
|
|
|
closeShare() {
|
|
|
|
|
this.showShare = false;
|
|
|
|
|
},
|
|
|
|
|
copyCardLink() {
|
|
|
|
|
const url = (this.card && this.card.wap_url) || '';
|
|
|
|
|
if (!url) {
|
|
|
|
|
uni.showToast({ title: '名片链接未返回,请稍后重试', icon: 'none' });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
uni.setClipboardData({
|
|
|
|
|
data: url,
|
|
|
|
|
success: () => uni.showToast({ title: '链接已复制', icon: 'success' }),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// H5: 优先 navigator.share(移动浏览器), 不支持则复制链接兜底
|
|
|
|
|
h5CardShare() {
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
const url = (this.card && this.card.wap_url) || '';
|
|
|
|
|
if (navigator && typeof navigator.share === 'function' && url) {
|
|
|
|
|
navigator.share({
|
|
|
|
|
title: ((this.card && this.card.name) || '我的名片') + '的名片',
|
|
|
|
|
url: url
|
|
|
|
|
}).catch(() => {});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// #endif
|
|
|
|
|
this.copyCardLink();
|
|
|
|
|
},
|
|
|
|
|
// 小程序/鸿蒙: 下载二维码后存相册(长按图片也可存, 抽屉底部有提示)
|
|
|
|
|
saveCardQr() {
|
|
|
|
|
const qrUrl = (this.card && this.card.qr_url) || '';
|
|
|
|
|
if (!qrUrl) return;
|
|
|
|
|
uni.downloadFile({
|
|
|
|
|
url: this.$util.img(qrUrl),
|
|
|
|
|
success: res => {
|
|
|
|
|
if (res.statusCode !== 200 || !res.tempFilePath) {
|
|
|
|
|
uni.showToast({ title: '二维码下载失败', icon: 'none' });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
uni.saveImageToPhotosAlbum({
|
|
|
|
|
filePath: res.tempFilePath,
|
|
|
|
|
success: () => uni.showToast({ title: '已保存到相册', icon: 'success' }),
|
|
|
|
|
fail: () => uni.showToast({ title: '保存失败,可复制链接分享', icon: 'none' })
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
fail: () => uni.showToast({ title: '二维码下载失败', icon: 'none' })
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 发名片: 跳原生转发中转页 /pages_tool/card/forward(内含 open-type=share 按钮,
|
|
|
|
|
* 直接拉起微信转发面板, 接收方落地 card/share 的 web-view 名片页)。
|
|
|
|
|
@@ -411,6 +551,29 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 快捷操作芯片: 高度/圆角对齐参考图(首个填充, 其余描边) */
|
|
|
|
|
.card-acts {
|
|
|
|
|
margin-top: 32rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
|
|
.act-chip {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
padding: 0 30rpx;
|
|
|
|
|
margin: 0 16rpx 16rpx 0;
|
|
|
|
|
border-radius: 32rpx;
|
|
|
|
|
|
|
|
|
|
.act-text {
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 发名片: 卡片外下方胶囊(背景色由 sendBtnStyle 内联) */
|
|
|
|
|
@@ -477,6 +640,122 @@ export default {
|
|
|
|
|
transform: scale(0.98);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 分享名片抽屉(复刻 pages_tool/card/detail.vue 的 share-mask/share-sheet, 类名加 cs- 前缀防撞) */
|
|
|
|
|
.cs-mask {
|
|
|
|
|
position: fixed;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
top: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
|
z-index: 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cs-sheet {
|
|
|
|
|
position: fixed;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
border-radius: 24rpx 24rpx 0 0;
|
|
|
|
|
padding: 20rpx 32rpx 40rpx;
|
|
|
|
|
z-index: 101;
|
|
|
|
|
transform: translateY(100%);
|
|
|
|
|
transition: transform 0.25s;
|
|
|
|
|
|
|
|
|
|
&.cs-sheet-show {
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-bar {
|
|
|
|
|
width: 36rpx;
|
|
|
|
|
height: 4rpx;
|
|
|
|
|
border-radius: 2rpx;
|
|
|
|
|
background-color: #e3e7ee;
|
|
|
|
|
margin: 0 auto 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-title {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #1a1f36;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-sub {
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
color: #9aa4b8;
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin: 8rpx 0 24rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-qr-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
|
|
|
|
.ss-qr {
|
|
|
|
|
width: 320rpx;
|
|
|
|
|
height: 320rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-link {
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
color: #9aa4b8;
|
|
|
|
|
background-color: #f6f7f9;
|
|
|
|
|
border-radius: 8rpx;
|
|
|
|
|
padding: 14rpx 20rpx;
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-btns {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
.ss-btn {
|
|
|
|
|
flex: 1;
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
line-height: 80rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
color: #333;
|
|
|
|
|
border: 1rpx solid #dcdfe6;
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
// 小程序端如有原生 button(当前无, 保险起见同样清默认样式)
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
overflow: visible;
|
|
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
& + .ss-btn {
|
|
|
|
|
margin-left: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 主按钮颜色走 shareBtnStyle 内联(主题色), 此处只兜底默认蓝
|
|
|
|
|
.ss-btn-main {
|
|
|
|
|
background-color: #119dff;
|
|
|
|
|
border-color: #119dff;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ss-tip {
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
color: #c0c4cc;
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes sk-shimmer {
|
|
|
|
|
0% {
|
|
|
|
|
background-position: -200rpx 0;
|
|
|
|
|
|