feat(diy-recommend-code): 为推荐码组件添加可定制化样式配置

1.  支持自定义标题字体大小、颜色,推荐码字体大小和颜色
2.  支持自定义卡片圆角、内边距
3.  支持自定义分享按钮背景色、文字颜色
4.  新增分享按钮显示控制、占位推荐码和换码文案配置
5.  统一将硬编码样式替换为动态绑定的可配置样式
This commit is contained in:
2026-08-07 15:00:52 +08:00
parent 2d19a653c9
commit 671c350d95

View File

@@ -51,7 +51,7 @@
<view v-if="showConsent" style="width:100%;box-sizing:border-box;margin-top:24rpx;background:#FFFFFF;border-radius:32rpx;padding:28rpx 28rpx;position:relative;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(0,0,0,0.06);">
<!-- 标题行 + 待获取标签 -->
<view style="display:flex;align-items:center;gap:12rpx;position:relative;z-index:1;">
<text style="font-size:34rpx;font-weight:800;color:#1A1A1A;">{{ value.title || '我的推荐码' }}</text>
<text :style="{ fontSize: px2rpx(value.titleFontSize || 17) + 'rpx', fontWeight: '800', color: value.titleColor || '#1A1A1A' }">{{ value.title || '我的推荐码' }}</text>
<view style="display:inline-flex;align-items:center;background:rgba(255,152,0,0.12);border-radius:16rpx;padding:4rpx 14rpx;gap:4rpx;">
<text style="font-size:18rpx;color:#FF8F00;">✓</text>
<text style="font-size:20rpx;color:#FF8F00;font-weight:600;">待获取推荐码</text>
@@ -87,10 +87,10 @@
<!-- ============ 推荐码卡片:仅在非 consent 且非首次加载时渲染 ============ -->
<block v-if="!showConsent && !(loadingCode && !code)">
<!-- ============ 预设 1:Gradient 渐变风格(默认)全部内联样式 ============ -->
<view v-if="stylePreset === 'gradient'" style="width:100%;box-sizing:border-box;margin-top:24rpx;background:#FFFFFF;border-radius:32rpx;padding:28rpx 28rpx;position:relative;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(0,0,0,0.06);">
<view v-if="stylePreset === 'gradient'" :style="{ width: '100%', boxSizing: 'border-box', marginTop: '24rpx', background: '#FFFFFF', borderRadius: px2rpx(value.borderRadius || 8) + 'rpx', padding: px2rpx(value.padding || 16) + 'rpx ' + px2rpx(value.padding || 16) + 'rpx', position: 'relative', overflow: 'hidden', boxShadow: '0 4rpx 16rpx rgba(0,0,0,0.06)' }">
<!-- 标题行 + 已获得推荐码标签 -->
<view style="display:flex;align-items:center;gap:12rpx;position:relative;z-index:1;">
<text style="font-size:34rpx;font-weight:800;color:#1A1A1A;">{{ value.title || '我的推荐码' }}</text>
<text :style="{ fontSize: px2rpx(value.titleFontSize || 17) + 'rpx', fontWeight: '800', color: value.titleColor || '#1A1A1A' }">{{ value.title || '我的推荐码' }}</text>
<view style="display:inline-flex;align-items:center;background:#52C41A;border-radius:16rpx;padding:4rpx 14rpx;gap:4rpx;">
<text style="font-size:18rpx;color:#FFFFFF;">✓</text>
<text style="font-size:20rpx;color:#FFFFFF;font-weight:600;">已获得推荐码</text>
@@ -100,19 +100,19 @@
<view style="margin-top:24rpx;background:#FFF8F0;border-radius:16rpx;padding:32rpx 20rpx 24rpx;position:relative;z-index:1;">
<!-- 推荐码居中显示 -->
<view style="text-align:center;">
<text style="font-size:64rpx;font-weight:900;color:#DC143C;letter-spacing:2rpx;font-family:'Courier New',monospace;">{{ code || '暂无' }}</text>
<text :style="{ fontSize: px2rpx(Math.max(16, Math.min(48, (Number(value.codeFontSize) || 28) * 0.93))) + 'rpx', fontWeight: '900', color: value.codeColor || '#DC143C', letterSpacing: '2rpx', fontFamily: 'Courier New, monospace' }">{{ code || value.placeholderCode || 'ABCD1234' }}</text>
</view>
<!-- 复制推荐码按钮:白色小按钮,红边框,在推荐码下方居中 -->
<view style="margin-top:12rpx;display:flex;justify-content:center;">
<view @tap="copyRecommendCode" style="width:fit-content;height:60rpx;display:flex;justify-content:center;align-items:center;background:#FFFFFF;border:2rpx solid #DC143C;border-radius:30rpx;padding:0 32rpx;gap:8rpx;">
<view @tap="copyRecommendCode" :style="{ width: 'fit-content', height: '60rpx', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#FFFFFF', border: '2rpx solid ' + (value.codeColor || '#DC143C'), borderRadius: '30rpx', padding: '0 32rpx', gap: '8rpx' }">
<text style="font-size:22rpx;">📋</text>
<text style="font-size:24rpx;color:#DC143C;font-weight:600;">复制推荐码</text>
<text :style="{ fontSize: '24rpx', color: value.codeColor || '#DC143C', fontWeight: '600' }">复制推荐码</text>
</view>
</view>
</view>
<!-- 立即分享链接按钮:黄橙渐变,小圆角,触发微信原生分享 -->
<button open-type="share" @tap="onShareClick" style="margin-top:20rpx;height:80rpx;display:flex;justify-content:center;align-items:center;background:linear-gradient(90deg,#FFC107 0%,#FF8F00 100%);border-radius:16rpx;box-shadow:0 4rpx 12rpx rgba(255,143,0,0.3);position:relative;z-index:1;border:none;line-height:1;">
<text style="font-size:28rpx;font-weight:700;color:#FFFFFF;">📤 {{ value.buttonText || '立即分享' }}</text>
<button v-if="value.showShareButton !== false" open-type="share" @tap="onShareClick" :style="{ marginTop: '20rpx', height: '80rpx', width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', background: (value.buttonBgColor && /^#[0-9a-f]{3,8}$/i.test(value.buttonBgColor)) ? value.buttonBgColor : 'linear-gradient(90deg,#FFC107 0%,#FF8F00 100%)', borderRadius: '16rpx', boxShadow: '0 4rpx 12rpx rgba(255,143,0,0.3)', position: 'relative', zIndex: '1', border: 'none', lineHeight: '1' }">
<text :style="{ fontSize: '28rpx', fontWeight: '700', color: value.buttonTextColor || '#FFFFFF' }">📤 {{ value.buttonText || '立即分享' }}</text>
</button>
<!-- showLink -->
<view v-if="isFeatureOn(value.showLink)" style="margin-top:20rpx;text-align:center;position:relative;z-index:1;">
@@ -126,7 +126,7 @@
</view>
<!-- ============ 预设 2:Minimal 极简风格(全部内联样式) ============ -->
<view v-if="stylePreset === 'minimal'" style="width:100%;box-sizing:border-box;margin-top:24rpx;background:linear-gradient(90deg,#FFFFFF 0%,#FFF8F8 30%,#FFF5F5 60%,#FFF0F0 100%);border-radius:32rpx;padding:28rpx 28rpx;position:relative;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(255,107,107,0.08);">
<view v-if="stylePreset === 'minimal'" :style="{ width: '100%', boxSizing: 'border-box', marginTop: '24rpx', background: 'linear-gradient(90deg,#FFFFFF 0%,#FFF8F8 30%,#FFF5F5 60%,#FFF0F0 100%)', borderRadius: px2rpx(value.borderRadius || 8) + 'rpx', padding: px2rpx(value.padding || 16) + 'rpx ' + px2rpx(value.padding || 16) + 'rpx', position: 'relative', overflow: 'hidden', boxShadow: '0 4rpx 16rpx rgba(255,107,107,0.08)' }">
<!-- 背景礼物装饰大图1(右上角,移至顶部) -->
<view style="position:absolute;top:-20rpx;right:-30rpx;z-index:0;">
<text style="font-size:200rpx;opacity:0.15;">🎁</text>
@@ -147,7 +147,7 @@
</view>
<!-- 标题行 + 已获得标签 -->
<view style="display:flex;align-items:center;gap:12rpx;position:relative;z-index:1;">
<text style="font-size:34rpx;font-weight:800;color:#1A1A1A;">{{ value.title || '我的推荐码' }}</text>
<text :style="{ fontSize: px2rpx(value.titleFontSize || 17) + 'rpx', fontWeight: '800', color: value.titleColor || '#1A1A1A' }">{{ value.title || '我的推荐码' }}</text>
<view style="display:inline-flex;align-items:center;background:rgba(255,107,107,0.15);border-radius:16rpx;padding:4rpx 14rpx;">
<text style="font-size:20rpx;color:#FF6B6B;font-weight:600;">已获得</text>
</view>
@@ -159,19 +159,19 @@
<!-- 推荐码红色虚线框:推荐码居中,圆角更圆,更紧凑 -->
<view style="margin-top:20rpx;background:rgba(255,255,255,0.7);border:2rpx dashed #FF6B6B;border-radius:32rpx;padding:12rpx 16rpx;position:relative;z-index:1;">
<view style="text-align:center;">
<text style="font-size:56rpx;font-weight:800;color:#FF4444;letter-spacing:2rpx;font-family:'Courier New',monospace;">{{ code || '暂无' }}</text>
<text :style="{ fontSize: px2rpx(Math.max(16, Math.min(48, (Number(value.codeFontSize) || 28) * 0.86))) + 'rpx', fontWeight: '800', color: value.codeColor || '#FF4444', letterSpacing: '2rpx', fontFamily: 'Courier New, monospace' }">{{ code || value.placeholderCode || 'ABCD1234' }}</text>
</view>
</view>
<!-- 复制推荐码按钮:白色小按钮,在虚线框下方、立即分享链接上方 -->
<view style="margin-top:14rpx;display:flex;justify-content:center;position:relative;z-index:1;">
<view @tap="copyRecommendCode" style="width:fit-content;height:60rpx;display:flex;justify-content:center;align-items:center;background:#FFFFFF;border:2rpx solid #FF6B6B;border-radius:30rpx;padding:0 32rpx;gap:8rpx;">
<view @tap="copyRecommendCode" :style="{ width: 'fit-content', height: '60rpx', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#FFFFFF', border: '2rpx solid ' + (value.codeColor || '#FF6B6B'), borderRadius: '30rpx', padding: '0 32rpx', gap: '8rpx' }">
<text style="font-size:22rpx;">📋</text>
<text style="font-size:24rpx;color:#FF6B6B;font-weight:600;">复制推荐码</text>
<text :style="{ fontSize: '24rpx', color: value.codeColor || '#FF6B6B', fontWeight: '600' }">复制推荐码</text>
</view>
</view>
<!-- 立即分享链接按钮:红色背景全宽铺满,触发微信原生分享 -->
<button open-type="share" @tap="onShareClick" style="margin-top:16rpx;height:76rpx;display:flex;justify-content:center;align-items:center;background:linear-gradient(90deg,#FF6B6B 0%,#FF4444 100%);border-radius:38rpx;box-shadow:0 4rpx 12rpx rgba(255,68,68,0.3);position:relative;z-index:1;border:none;line-height:1;">
<text style="font-size:27rpx;font-weight:700;color:#FFFFFF;">📤 {{ value.buttonText || '立即分享' }}</text>
<button v-if="value.showShareButton !== false" open-type="share" @tap="onShareClick" :style="{ marginTop: '16rpx', height: '76rpx', width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', background: (value.buttonBgColor && /^#[0-9a-f]{3,8}$/i.test(value.buttonBgColor)) ? value.buttonBgColor : 'linear-gradient(90deg,#FF6B6B 0%,#FF4444 100%)', borderRadius: '38rpx', boxShadow: '0 4rpx 12rpx rgba(255,68,68,0.3)', position: 'relative', zIndex: '1', border: 'none', lineHeight: '1' }">
<text :style="{ fontSize: '27rpx', fontWeight: '700', color: value.buttonTextColor || '#FFFFFF' }">📤 {{ value.buttonText || '立即分享' }}</text>
</button>
<!-- showLink -->
<view v-if="isFeatureOn(value.showLink)" style="margin-top:16rpx;text-align:center;position:relative;z-index:1;">
@@ -185,14 +185,14 @@
</view>
<!-- ============ 预设 3:Card 卡片风格(全部内联样式) ============ -->
<view v-if="stylePreset === 'card'" style="width:100%;box-sizing:border-box;margin-top:24rpx;background:linear-gradient(180deg,#FFF9F5 0%,#FFF5F0 100%);border-radius:32rpx;padding:28rpx 28rpx;position:relative;overflow:hidden;">
<view v-if="stylePreset === 'card'" :style="{ width: '100%', boxSizing: 'border-box', marginTop: '24rpx', background: 'linear-gradient(180deg,#FFF9F5 0%,#FFF5F0 100%)', borderRadius: px2rpx(value.borderRadius || 8) + 'rpx', padding: px2rpx(value.padding || 16) + 'rpx ' + px2rpx(value.padding || 16) + 'rpx', position: 'relative', overflow: 'hidden' }">
<!-- 右上角礼物装饰(开盖礼物盒) -->
<view style="position:absolute;top:16rpx;right:20rpx;z-index:2;">
<text style="font-size:52rpx;">🎁</text>
</view>
<!-- 标题行 + 已生效标签 -->
<view style="display:flex;align-items:center;gap:12rpx;position:relative;z-index:1;">
<text style="font-size:34rpx;font-weight:800;color:#1A1A1A;">{{ value.title || '我的推荐码' }}</text>
<text :style="{ fontSize: px2rpx(value.titleFontSize || 17) + 'rpx', fontWeight: '800', color: value.titleColor || '#1A1A1A' }">{{ value.title || '我的推荐码' }}</text>
<view style="display:inline-flex;align-items:center;background:rgba(255,107,107,0.12);border-radius:16rpx;padding:4rpx 14rpx;">
<text style="font-size:20rpx;color:#FF6B6B;font-weight:600;">✓ 已生效</text>
</view>
@@ -204,19 +204,19 @@
<!-- 推荐码红色虚线框:居中,圆角,紧凑 -->
<view style="margin-top:20rpx;display:flex;justify-content:center;position:relative;z-index:1;">
<view style="background:rgba(255,255,255,0.7);border:2rpx dashed #FF6B6B;border-radius:32rpx;padding:12rpx 32rpx;text-align:center;">
<text style="font-size:48rpx;font-weight:800;color:#FF4444;letter-spacing:2rpx;font-family:'Courier New',monospace;">{{ code || '暂无' }}</text>
<text :style="{ fontSize: px2rpx(Math.max(16, Math.min(48, (Number(value.codeFontSize) || 28) * 0.71))) + 'rpx', fontWeight: '800', color: value.codeColor || '#FF4444', letterSpacing: '2rpx', fontFamily: 'Courier New, monospace' }">{{ code || value.placeholderCode || 'ABCD1234' }}</text>
</view>
</view>
<!-- 复制推荐码按钮:白色小按钮,在虚线框下方、立即分享链接上方,居中 -->
<view style="margin-top:14rpx;display:flex;justify-content:center;position:relative;z-index:1;">
<view @tap="copyRecommendCode" style="width:fit-content;height:60rpx;display:flex;justify-content:center;align-items:center;background:#FFFFFF;border:2rpx solid #FF6B6B;border-radius:30rpx;padding:0 32rpx;gap:8rpx;">
<view @tap="copyRecommendCode" :style="{ width: 'fit-content', height: '60rpx', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#FFFFFF', border: '2rpx solid ' + (value.codeColor || '#FF6B6B'), borderRadius: '30rpx', padding: '0 32rpx', gap: '8rpx' }">
<text style="font-size:22rpx;">📋</text>
<text style="font-size:24rpx;color:#FF6B6B;font-weight:600;">复制推荐码</text>
<text :style="{ fontSize: '24rpx', color: value.codeColor || '#FF6B6B', fontWeight: '600' }">复制推荐码</text>
</view>
</view>
<!-- 立即分享链接按钮:全宽铺满白底红边框,触发微信原生分享 -->
<button open-type="share" @tap="onShareClick" style="margin-top:16rpx;height:76rpx;display:flex;justify-content:center;align-items:center;background:#FFFFFF;border:2rpx solid #FF6B6B;border-radius:38rpx;position:relative;z-index:1;line-height:1;">
<text style="font-size:27rpx;font-weight:600;color:#FF6B6B;">📤 {{ value.buttonText || '立即分享' }}</text>
<button v-if="value.showShareButton !== false" open-type="share" @tap="onShareClick" :style="{ marginTop: '16rpx', height: '76rpx', width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', background: (value.buttonBgColor && /^#[0-9a-f]{3,8}$/i.test(value.buttonBgColor)) ? value.buttonBgColor : '#FFFFFF', border: (value.buttonBgColor && /^#[0-9a-f]{3,8}$/i.test(value.buttonBgColor)) ? 'none' : '2rpx solid ' + (value.codeColor || '#FF6B6B'), borderRadius: '38rpx', position: 'relative', zIndex: '1', lineHeight: '1' }">
<text :style="{ fontSize: '27rpx', fontWeight: '600', color: value.codeColor || '#FF6B6B' }">📤 {{ value.buttonText || '立即分享' }}</text>
</button>
<!-- showLink -->
<view v-if="isFeatureOn(value.showLink)" style="margin-top:16rpx;text-align:center;position:relative;z-index:1;">
@@ -230,9 +230,9 @@
</view>
<!-- ============ 预设 4:Horizontal 横向风格(全部内联样式,匹配参考图) ============ -->
<view v-if="stylePreset === 'horizontal'" style="width:100%;box-sizing:border-box;margin-top:24rpx;background:#FFFFFF;border-radius:32rpx;padding:28rpx 28rpx;position:relative;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(0,0,0,0.06);">
<view v-if="stylePreset === 'horizontal'" :style="{ width: '100%', boxSizing: 'border-box', marginTop: '24rpx', background: '#FFFFFF', borderRadius: px2rpx(value.borderRadius || 8) + 'rpx', padding: px2rpx(value.padding || 16) + 'rpx ' + px2rpx(value.padding || 16) + 'rpx', position: 'relative', overflow: 'hidden', boxShadow: '0 4rpx 16rpx rgba(0,0,0,0.06)' }">
<!-- 卡片顶部:主标题 -->
<text style="font-size:34rpx;font-weight:800;color:#1A1A1A;display:block;">{{ value.title || '我的推荐码' }}</text>
<text :style="{ fontSize: px2rpx(value.titleFontSize || 17) + 'rpx', fontWeight: '800', color: value.titleColor || '#1A1A1A', display: 'block' }">{{ value.title || '我的推荐码' }}</text>
<!-- 内容主体框:浅橙细边框,极浅米白底色 -->
<view style="margin-top:20rpx;background:#FFFCF8;border:2rpx solid #FFE0B2;border-radius:20rpx;padding:24rpx 24rpx 20rpx;position:relative;overflow:hidden;">
<!-- 2.1 状态标签(左上角) -->
@@ -252,23 +252,23 @@
</view>
<!-- 2.3 推荐码核心文本(左对齐) -->
<view style="margin-top:20rpx;position:relative;z-index:1;">
<text style="font-size:72rpx;font-weight:900;color:#FF4444;letter-spacing:2rpx;font-family:'Courier New',monospace;">{{ code || '暂无' }}</text>
<text :style="{ fontSize: px2rpx(Math.max(16, Math.min(48, (Number(value.codeFontSize) || 28) * 1.07))) + 'rpx', fontWeight: '900', color: value.codeColor || '#FF4444', letterSpacing: '2rpx', fontFamily: 'Courier New, monospace' }">{{ code || value.placeholderCode || 'ABCD1234' }}</text>
</view>
<!-- 2.4 + 2.5 按钮行:左复制、右分享,上下错落 -->
<view style="margin-top:16rpx;display:flex;align-items:flex-end;justify-content:space-between;gap:16rpx;position:relative;z-index:1;">
<!-- 左下角:复制推荐码按钮(描边圆角胶囊) -->
<view @tap="copyRecommendCode" style="height:64rpx;display:flex;justify-content:center;align-items:center;background:#FFFFFF;border:2rpx solid #FFB74D;border-radius:32rpx;padding:0 24rpx;gap:6rpx;">
<view @tap="copyRecommendCode" :style="{ height: '64rpx', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#FFFFFF', border: '2rpx solid ' + (value.codeColor || '#FFB74D'), borderRadius: '32rpx', padding: '0 24rpx', gap: '6rpx' }">
<text style="font-size:22rpx;">📋</text>
<text style="font-size:24rpx;color:#FF8F00;font-weight:600;">复制推荐码</text>
<text :style="{ fontSize: '24rpx', color: value.codeColor || '#FF8F00', fontWeight: '600' }">复制推荐码</text>
</view>
<!-- 右下角:立即分享链接按钮(渐变橙色圆角胶囊,靠右,触发微信原生分享) -->
<button open-type="share" @tap="onShareClick" style="height:72rpx;display:flex;justify-content:center;align-items:center;background:linear-gradient(90deg,#FF9800 0%,#FF4444 100%);border-radius:36rpx;padding:0 40rpx;box-shadow:0 4rpx 12rpx rgba(255,68,68,0.25);margin-bottom:-4rpx;border:none;line-height:1;">
<text style="font-size:27rpx;font-weight:700;color:#FFFFFF;">📤 {{ value.buttonText || '立即分享' }}</text>
<button v-if="value.showShareButton !== false" open-type="share" @tap="onShareClick" :style="{ height: '72rpx', display: 'flex', justifyContent: 'center', alignItems: 'center', background: (value.buttonBgColor && /^#[0-9a-f]{3,8}$/i.test(value.buttonBgColor)) ? value.buttonBgColor : 'linear-gradient(90deg,#FF9800 0%,#FF4444 100%)', borderRadius: '36rpx', padding: '0 40rpx', boxShadow: '0 4rpx 12rpx rgba(255,68,68,0.25)', marginBottom: '-4rpx', border: 'none', lineHeight: '1' }">
<text :style="{ fontSize: '27rpx', fontWeight: '700', color: value.buttonTextColor || '#FFFFFF' }">📤 {{ value.buttonText || '立即分享' }}</text>
</button>
</view>
</view>
<!-- 换一个新码 -->
<view v-if="isFeatureOn(value.allowRegenerate)" style="margin-top:16rpx;display:flex;justify-content:center;">
<view v-if="value.allowRegenerate === true" style="margin-top:16rpx;display:flex;justify-content:center;">
<view @tap="regenerate" style="background:rgba(255,68,68,0.06);border-radius:24rpx;padding:8rpx 24rpx;">
<text style="font-size:22rpx;color:#FF4444;font-weight:600;">{{ value.placeholderRegenerateText || '换一个新码' }}</text>
</view>