Преглед на файлове

feat(cfc-frontend): ContentSharePoster 参数化五维配色+简介/邀请语/价格行+居中弹窗

iwt преди 1 месец
родител
ревизия
3a84ff9d11
променени са 1 файла, в които са добавени 68 реда и са изтрити 36 реда
  1. 68 36
      cfc-frontend/components/ContentSharePoster.vue

+ 68 - 36
cfc-frontend/components/ContentSharePoster.vue

@@ -4,7 +4,6 @@
       <canvas canvas-id="contentPosterCanvas" class="poster-canvas" id="contentPosterCanvas"></canvas>
       <canvas canvas-id="contentPosterCanvas" class="poster-canvas" id="contentPosterCanvas"></canvas>
       <view class="poster-actions">
       <view class="poster-actions">
         <button class="poster-btn save" @click="savePoster">保存到相册</button>
         <button class="poster-btn save" @click="savePoster">保存到相册</button>
-        <button class="poster-btn cancel" @click="$emit('close')">取消</button>
       </view>
       </view>
     </view>
     </view>
   </view>
   </view>
@@ -18,7 +17,12 @@ export default {
     title: { type: String, default: '' },
     title: { type: String, default: '' },
     coverImage: { type: String, default: '' },
     coverImage: { type: String, default: '' },
     qrCodeBase64: { type: String, default: '' },
     qrCodeBase64: { type: String, default: '' },
-    typeLabel: { type: String, default: '好物推荐' }
+    typeLabel: { type: String, default: '好物推荐' },
+    dimensionCode: { type: String, default: '' },
+    summary: { type: String, default: '' },
+    priceText: { type: String, default: '' },
+    ctaText: { type: String, default: '长按识别二维码 · 查看详情' },
+    inviteText: { type: String, default: '' }
   },
   },
   watch: {
   watch: {
     show(val) {
     show(val) {
@@ -30,25 +34,36 @@ export default {
     }
     }
   },
   },
   methods: {
   methods: {
+    getColors() {
+      var map = {
+        body: { main: '#FF8C42', dark: '#EA580C', light: '#FFF7ED' },
+        mind: { main: '#FF6B9D', dark: '#DB2777', light: '#FDF2F8' },
+        wisdom: { main: '#6366F1', dark: '#4F46E5', light: '#EEF2FF' },
+        action: { main: '#10B981', dark: '#059669', light: '#ECFDF5' },
+        wealth: { main: '#F59E0B', dark: '#D97706', light: '#FFFBEB' }
+      }
+      return map[this.dimensionCode] || { main: '#F97316', dark: '#EA580C', light: '#FFF7ED' }
+    },
     drawPoster() {
     drawPoster() {
       var ctx = uni.createCanvasContext('contentPosterCanvas', this)
       var ctx = uni.createCanvasContext('contentPosterCanvas', this)
       var w = 500
       var w = 500
       var h = 800
       var h = 800
+      var colors = this.getColors()
 
 
       var gradient = ctx.createLinearGradient(0, 0, w * 0.3, h)
       var gradient = ctx.createLinearGradient(0, 0, w * 0.3, h)
-      gradient.addColorStop(0, '#F97316')
-      gradient.addColorStop(0.55, '#EA580C')
-      gradient.addColorStop(1, '#D94F0A')
+      gradient.addColorStop(0, colors.main)
+      gradient.addColorStop(0.55, colors.dark)
+      gradient.addColorStop(1, colors.dark)
       ctx.setFillStyle(gradient)
       ctx.setFillStyle(gradient)
       ctx.fillRect(0, 0, w, h)
       ctx.fillRect(0, 0, w, h)
 
 
-      this._drawTopDecoration(ctx, w)
+      this._drawTopDecoration(ctx, w, colors)
 
 
       var cardX = 28
       var cardX = 28
       var cardY = 112
       var cardY = 112
       var cardW = 444
       var cardW = 444
       var cardH = 600
       var cardH = 600
-      this._drawContentCard(ctx, cardX, cardY, cardW, cardH)
+      this._drawContentCard(ctx, cardX, cardY, cardW, cardH, colors)
 
 
       var coverY = cardY + 20
       var coverY = cardY + 20
       var coverW = cardW - 40
       var coverW = cardW - 40
@@ -64,20 +79,20 @@ export default {
             } else {
             } else {
               self._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
               self._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
             }
             }
-            self._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH)
+            self._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH, colors)
           },
           },
           fail: function() {
           fail: function() {
             self._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
             self._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
-            self._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH)
+            self._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH, colors)
           }
           }
         })
         })
       } else {
       } else {
         this._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
         this._drawCoverPlaceholder(ctx, cardX + 20, coverY, coverW, coverH)
-        this._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH)
+        this._drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH, colors)
       }
       }
     },
     },
 
 
-    _drawTopDecoration(ctx, w) {
+    _drawTopDecoration(ctx, w, colors) {
       var centerX = w / 2
       var centerX = w / 2
       var dotColors = ['#FF8C42', '#6366F1', '#F59E0B', '#10B981', '#FF6B9D']
       var dotColors = ['#FF8C42', '#6366F1', '#F59E0B', '#10B981', '#FF6B9D']
       var dotY = 28
       var dotY = 28
@@ -112,12 +127,12 @@ export default {
       ctx.stroke()
       ctx.stroke()
     },
     },
 
 
-    _drawContentCard(ctx, x, y, w, h) {
+    _drawContentCard(ctx, x, y, w, h, colors) {
       ctx.setFillStyle('rgba(0,0,0,0.04)')
       ctx.setFillStyle('rgba(0,0,0,0.04)')
       this._roundRect(ctx, x + 2, y + 3, w, h, 16)
       this._roundRect(ctx, x + 2, y + 3, w, h, 16)
       ctx.fill()
       ctx.fill()
 
 
-      ctx.setFillStyle('#FFFCF5')
+      ctx.setFillStyle(colors.light)
       this._roundRect(ctx, x, y, w, h, 16)
       this._roundRect(ctx, x, y, w, h, 16)
       ctx.fill()
       ctx.fill()
     },
     },
@@ -134,16 +149,17 @@ export default {
       ctx.fillText('暂无封面图', x + w / 2, y + h / 2)
       ctx.fillText('暂无封面图', x + w / 2, y + h / 2)
     },
     },
 
 
-    _drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH) {
+    _drawContentAfterCover(ctx, w, h, cardX, cardW, coverY, coverH, colors) {
       var self = this
       var self = this
 
 
       var labelY = coverY + coverH + 16
       var labelY = coverY + coverH + 16
-      ctx.setFillStyle('#F97316')
+      ctx.setFillStyle(colors.main)
       ctx.setFontSize(13)
       ctx.setFontSize(13)
       ctx.setTextAlign('left')
       ctx.setTextAlign('left')
       ctx.setTextBaseline('top')
       ctx.setTextBaseline('top')
       ctx.fillText(this.typeLabel, cardX + 20, labelY)
       ctx.fillText(this.typeLabel, cardX + 20, labelY)
 
 
+      // 标题(2行截断)
       var titleY = labelY + 22
       var titleY = labelY + 22
       ctx.setFillStyle('#1C1917')
       ctx.setFillStyle('#1C1917')
       ctx.setFontSize(18)
       ctx.setFontSize(18)
@@ -151,16 +167,38 @@ export default {
       ctx.setTextBaseline('top')
       ctx.setTextBaseline('top')
       this._drawWrappedText(ctx, this.title || '精彩内容', cardX + 20, titleY, cardW - 40, 24, 2)
       this._drawWrappedText(ctx, this.title || '精彩内容', cardX + 20, titleY, cardW - 40, 24, 2)
 
 
-      var hintY = titleY + 56
-      ctx.setFontSize(13)
+      // 价格行(商品用;空则跳过)
+      var priceY = titleY + 56
+      if (this.priceText) {
+        ctx.setFillStyle(colors.main)
+        ctx.setFontSize(17)
+        ctx.setTextAlign('left')
+        ctx.setTextBaseline('top')
+        ctx.fillText(this.priceText, cardX + 20, priceY)
+      }
+
+      // 简介(1-2行灰字;空则跳过)
+      var summaryY = (this.priceText ? priceY + 34 : priceY)
+      if (this.summary) {
+        ctx.setFillStyle('#78716C')
+        ctx.setFontSize(13)
+        ctx.setTextAlign('left')
+        ctx.setTextBaseline('top')
+        this._drawWrappedText(ctx, this.summary, cardX + 20, summaryY, cardW - 40, 20, 2)
+      }
+
+      // 邀请语(二维码上方)
+      var inviteY = (this.summary ? summaryY + 48 : summaryY)
       ctx.setFillStyle('#A8A29E')
       ctx.setFillStyle('#A8A29E')
+      ctx.setFontSize(13)
       ctx.setTextAlign('center')
       ctx.setTextAlign('center')
       ctx.setTextBaseline('top')
       ctx.setTextBaseline('top')
-      ctx.fillText('长按识别二维码 · 查看详情', w / 2, hintY)
+      ctx.fillText(this.inviteText || '长按识别二维码 · 查看详情', w / 2, inviteY)
 
 
-      var qrSize = 160
+      // 二维码
+      var qrSize = 150
       var qrX = (w - qrSize) / 2
       var qrX = (w - qrSize) / 2
-      var qrY = hintY + 20
+      var qrY = inviteY + 24
 
 
       if (this.qrCodeBase64) {
       if (this.qrCodeBase64) {
         var base64Data = this.qrCodeBase64
         var base64Data = this.qrCodeBase64
@@ -189,16 +227,16 @@ export default {
             ctx.stroke()
             ctx.stroke()
 
 
             ctx.drawImage(filePath, qrX, qrY, qrSize, qrSize)
             ctx.drawImage(filePath, qrX, qrY, qrSize, qrSize)
-            self._drawBottomDecoration(ctx, w, h, qrY, qrSize)
+            self._drawBottomDecoration(ctx, w, h, qrY, qrSize, colors)
           },
           },
           fail: function() {
           fail: function() {
             self._drawQrPlaceholder(ctx, qrX, qrY, qrSize)
             self._drawQrPlaceholder(ctx, qrX, qrY, qrSize)
-            self._drawBottomDecoration(ctx, w, h, qrY, qrSize)
+            self._drawBottomDecoration(ctx, w, h, qrY, qrSize, colors)
           }
           }
         })
         })
       } else {
       } else {
         this._drawQrPlaceholder(ctx, qrX, qrY, qrSize)
         this._drawQrPlaceholder(ctx, qrX, qrY, qrSize)
-        this._drawBottomDecoration(ctx, w, h, qrY, qrSize)
+        this._drawBottomDecoration(ctx, w, h, qrY, qrSize, colors)
       }
       }
     },
     },
 
 
@@ -253,12 +291,12 @@ export default {
       ctx.fillText('二维码加载中', x + size / 2, y + size / 2)
       ctx.fillText('二维码加载中', x + size / 2, y + size / 2)
     },
     },
 
 
-    _drawBottomDecoration(ctx, w, h, qrY, qrSize) {
+    _drawBottomDecoration(ctx, w, h, qrY, qrSize, colors) {
       var centerX = w / 2
       var centerX = w / 2
       var bottomY = qrY + qrSize + 16
       var bottomY = qrY + qrSize + 16
 
 
-      ctx.setFillStyle('rgba(249,115,22,0.15)')
       var diamondY = bottomY + 6
       var diamondY = bottomY + 6
+      ctx.setFillStyle('rgba(0,0,0,0.06)')
       ctx.beginPath()
       ctx.beginPath()
       ctx.moveTo(centerX - 76, diamondY)
       ctx.moveTo(centerX - 76, diamondY)
       ctx.lineTo(centerX - 72, diamondY - 4)
       ctx.lineTo(centerX - 72, diamondY - 4)
@@ -274,11 +312,11 @@ export default {
       ctx.closePath()
       ctx.closePath()
       ctx.fill()
       ctx.fill()
 
 
-      ctx.setFillStyle('#F97316')
+      ctx.setFillStyle(colors.main)
       ctx.setFontSize(18)
       ctx.setFontSize(18)
       ctx.setTextAlign('center')
       ctx.setTextAlign('center')
       ctx.setTextBaseline('top')
       ctx.setTextBaseline('top')
-      ctx.fillText('扫码查看详情', centerX, bottomY)
+      ctx.fillText(this.ctaText || '长按识别二维码 · 查看详情', centerX, bottomY)
 
 
       var dotColors = ['#FF8C42', '#6366F1', '#F59E0B', '#10B981', '#FF6B9D']
       var dotColors = ['#FF8C42', '#6366F1', '#F59E0B', '#10B981', '#FF6B9D']
       var dotY = h - 22
       var dotY = h - 22
@@ -370,14 +408,14 @@ export default {
   align-items: center;
   align-items: center;
 }
 }
 .poster-canvas {
 .poster-canvas {
-  width: 500px;
-  height: 800px;
+  width: 620rpx;
+  height: 992rpx;
   border-radius: 16rpx;
   border-radius: 16rpx;
 }
 }
 .poster-actions {
 .poster-actions {
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
-  width: 500px;
+  width: 620rpx;
   margin-top: 30rpx;
   margin-top: 30rpx;
 }
 }
 .poster-btn {
 .poster-btn {
@@ -393,12 +431,6 @@ export default {
   background: #ffffff;
   background: #ffffff;
   color: #F97316;
   color: #F97316;
   font-weight: 600;
   font-weight: 600;
-  margin-bottom: 16rpx;
 }
 }
 .poster-btn.save:active { opacity: 0.85; }
 .poster-btn.save:active { opacity: 0.85; }
-.poster-btn.cancel {
-  background: rgba(255, 255, 255, 0.15);
-  color: #ffffff;
-}
-.poster-btn.cancel:active { opacity: 0.85; }
 </style>
 </style>