- mini.vue: 8 detail 字段消费(三列行/复制范围外观/QR 多行/URL 行/hero 徽章) + rowsBlockStyle/qrBlockCustomStyle computed(与操作区 actsBlockStyle 同款模式) + rowsFinalStyle/qrBlockFinalStyle 合并独立块样式 - show.vue/self.vue: miniConfig 透传 14 字段(8 detail + 6 独立样式) - 测试 ×3: 2.19.10 契约锁(配置层/透传/面板/预览消费/反例: layoutCards 已移除) 前端 7 套 123 项全绿
252 lines
7.3 KiB
Vue
252 lines
7.3 KiB
Vue
<template>
|
|
<view data-component-name="diy-card-show" class="diy-card-show">
|
|
<diy-card-mini
|
|
:card="card"
|
|
:config="miniConfig"
|
|
:loading="loading"
|
|
empty-tip="商家还未选择名片"
|
|
@act="doAct"
|
|
@row-act="doAct"
|
|
@detail="goDetail"
|
|
></diy-card-mini>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
// 数字名片 · 精选名片(装修组件)
|
|
// 视觉基件 diy-card-mini(封面/渐变/Logo/主题色/折叠/芯片/二维码), 本文件只管数据
|
|
export default {
|
|
name: 'diy-card-show',
|
|
props: {
|
|
value: { type: Object }
|
|
},
|
|
data() {
|
|
return {
|
|
card: null,
|
|
loading: false,
|
|
};
|
|
},
|
|
computed: {
|
|
miniConfig() {
|
|
const v = this.value || {};
|
|
return {
|
|
bgColor: v.bgColor,
|
|
nameColor: v.nameColor,
|
|
infoColor: v.infoColor,
|
|
labelColor: v.labelColor,
|
|
borderRadius: v.borderRadius,
|
|
padding: v.padding,
|
|
// 字号定制(px 口径, 缺省时基件按历史默认值渲染) —— 2.17 补齐:
|
|
// 此前 show 漏透传 7 个字号字段(面板配置不生效), 与 self 对齐
|
|
nameSize: v.nameSize,
|
|
cardTitleSize: v.cardTitleSize,
|
|
subSize: v.subSize,
|
|
labelSize: v.labelSize,
|
|
valueSize: v.valueSize,
|
|
actSize: v.actSize,
|
|
btnSize: v.btnSize,
|
|
showQuick: v.showQuick,
|
|
showDetailBtn: v.showDetailBtn,
|
|
detailBtnText: v.detailBtnText,
|
|
// 2.0 新增视觉开关
|
|
useCover: v.useCover,
|
|
showGradient: v.showGradient,
|
|
showLogo: v.showLogo,
|
|
showShadow: v.showShadow,
|
|
showRows: v.showRows,
|
|
maxRows: v.maxRows,
|
|
showQr: v.showQr,
|
|
qrTip: v.qrTip,
|
|
// 3.0 A+B 视觉升级
|
|
showRowIcons: v.showRowIcons,
|
|
rowTap: v.rowTap,
|
|
qrPosition: v.qrPosition,
|
|
// 3.1 头像开关 + 二维码样式/微调
|
|
showAvatar: v.showAvatar,
|
|
qrStyle: v.qrStyle,
|
|
qrSize: v.qrSize,
|
|
qrOffsetX: v.qrOffsetX,
|
|
qrOffsetY: v.qrOffsetY,
|
|
qrTipShow: v.qrTipShow,
|
|
// 2.17 双形态: 渐变头部 / 宫格快捷操作 / 资料区标题 / 复制按钮
|
|
headStyle: v.headStyle,
|
|
headNameColor: v.headNameColor,
|
|
headSubColor: v.headSubColor,
|
|
actsLayout: v.actsLayout,
|
|
actGridColorMode: v.actGridColorMode,
|
|
showRowsTitle: v.showRowsTitle,
|
|
rowsTitle: v.rowsTitle,
|
|
showCopyBtn: v.showCopyBtn,
|
|
// 2.18: 操作区位置/独立块样式/每按钮图标/自定义二维码图
|
|
actsPosition: v.actsPosition,
|
|
actsBlockBg: v.actsBlockBg,
|
|
actsBlockRadius: v.actsBlockRadius,
|
|
actsBlockPad: v.actsBlockPad,
|
|
actIcons: v.actIcons,
|
|
qrImage: v.qrImage,
|
|
// 2.19: 默认动作显隐/文案 + 自定义动作(基件 acts computed 合成)
|
|
actVis: v.actVis,
|
|
actDeleted: v.actDeleted,
|
|
actLabels: v.actLabels,
|
|
actOrder: v.actOrder,
|
|
customActs: v.customActs,
|
|
// 2.19.10 detail 版式对齐(三列行/复制范围外观/qrTip 富文本/URL 行/hero 徽章/分卡)
|
|
showRowLabels: v.showRowLabels,
|
|
copyBtnScope: v.copyBtnScope,
|
|
copyBtnLook: v.copyBtnLook,
|
|
qrTipEm: v.qrTipEm,
|
|
qrTipSub: v.qrTipSub,
|
|
qrUrlShow: v.qrUrlShow,
|
|
badgeShow: v.badgeShow,
|
|
badgeText: v.badgeText,
|
|
rowsBlockBg: v.rowsBlockBg,
|
|
rowsBlockRadius: v.rowsBlockRadius,
|
|
rowsBlockPad: v.rowsBlockPad,
|
|
qrBlockBg: v.qrBlockBg,
|
|
qrBlockRadius: v.qrBlockRadius,
|
|
qrBlockPad: v.qrBlockPad,
|
|
};
|
|
},
|
|
},
|
|
watch: {
|
|
'value.cardId'() {
|
|
this.fetchData();
|
|
},
|
|
},
|
|
mounted() {
|
|
this.fetchData();
|
|
},
|
|
methods: {
|
|
fetchData() {
|
|
const cardId = String((this.value || {}).cardId || '').trim();
|
|
if (cardId === '') {
|
|
this.card = null;
|
|
return;
|
|
}
|
|
this.loading = true;
|
|
this.$api.sendRequest({
|
|
url: '/card/api/diy/card',
|
|
data: { card_id: cardId },
|
|
success: res => {
|
|
this.loading = false;
|
|
this.card = (res.code == 0 && res.data && res.data.card) ? res.data.card : null;
|
|
},
|
|
fail: () => {
|
|
this.loading = false;
|
|
this.card = null;
|
|
},
|
|
});
|
|
},
|
|
doAct(act) {
|
|
if (!act) return;
|
|
// save(存通讯录): value 为空, 字段由本组件从 card 组装(白名单口径)
|
|
if (act.type === 'save') {
|
|
this.goSaveContact();
|
|
return;
|
|
}
|
|
// map(导航): value 留空回落名片地址(2.19.3)
|
|
if (act.type === 'map' && !act.value && this.card && this.card.address) {
|
|
act = Object.assign({}, act, { value: this.card.address });
|
|
}
|
|
if (!act.value) return;
|
|
if (act.type === 'tel') {
|
|
uni.makePhoneCall({ phoneNumber: act.value, fail: () => {} });
|
|
} else if (act.type === 'wx') {
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '微信号已复制', icon: 'none' }),
|
|
});
|
|
} else if (act.type === 'mail') {
|
|
// #ifdef H5
|
|
window.location.href = 'mailto:' + act.value;
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '邮箱已复制', icon: 'none' }),
|
|
});
|
|
// #endif
|
|
} else if (act.type === 'sms') {
|
|
// #ifdef H5
|
|
window.location.href = 'sms:' + act.value;
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '号码已复制,请到短信粘贴', icon: 'none' }),
|
|
});
|
|
// #endif
|
|
} else if (act.type === 'map') {
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '地址已复制,可粘贴到地图导航', icon: 'none' }),
|
|
});
|
|
} else if (act.type === 'link') {
|
|
var isHttp = act.value.indexOf('http://') === 0 || act.value.indexOf('https://') === 0;
|
|
if (isHttp) {
|
|
// #ifdef H5
|
|
window.location.href = act.value;
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '链接已复制,请在浏览器打开', icon: 'none' }),
|
|
});
|
|
// #endif
|
|
} else {
|
|
this.$util.redirectTo(act.value, {});
|
|
}
|
|
} else {
|
|
uni.setClipboardData({
|
|
data: act.value,
|
|
success: () => uni.showToast({ title: '已复制', icon: 'none' }),
|
|
});
|
|
}
|
|
},
|
|
goDetail(card) {
|
|
if (!card || !card.card_id) return;
|
|
this.$util.redirectTo('/pages_tool/card/detail', { card_id: card.card_id });
|
|
},
|
|
/**
|
|
* 存通讯录(2.17.1): 字段全部从 card 组装 —— rows 已过 shouldShow
|
|
* 白名单(商家隐藏的字段不下发也不落通讯录, 隐私口径与后端一致),
|
|
* name/company/job_title 为公开头部字段直接取。
|
|
* 键名与 save-contact.vue onLoad 的 keys 一一对应。
|
|
*/
|
|
goSaveContact() {
|
|
const c = this.card || {};
|
|
const map = {};
|
|
(Array.isArray(c.rows) ? c.rows : []).forEach(r => {
|
|
if (r && r.field) map[r.field] = String(r.value || '');
|
|
});
|
|
// #ifdef H5
|
|
// H5 无通讯录 API: 复制资料文本兜底(小程序端走 save-contact 原生页)
|
|
const text = [c.name, map.mobile, map.email, c.company, c.job_title].filter(Boolean).join(' ');
|
|
uni.setClipboardData({
|
|
data: text,
|
|
success: () => uni.showToast({ title: '名片资料已复制', icon: 'none' }),
|
|
});
|
|
return;
|
|
// #endif
|
|
this.$util.redirectTo('/pages_tool/card/save-contact', {
|
|
name: c.name || '',
|
|
mobile: map.mobile || '',
|
|
company: c.company || '',
|
|
job_title: c.job_title || '',
|
|
email: map.email || '',
|
|
website: map.website || '',
|
|
address: map.address || '',
|
|
remark: map.remark || '',
|
|
wechat: map.wechat || '',
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.diy-card-show {
|
|
width: 100%;
|
|
}
|
|
</style>
|