DimensionVisitorCard.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <template>
  2. <view class="dvc">
  3. <!-- 价值预览卡:维度浅底 + 维度色 CTA -->
  4. <view class="dvc-card" :style="{ background: softColor }">
  5. <view class="dvc-head">
  6. <text class="dvc-title">{{ cardTitle }}</text>
  7. <text class="dvc-sub">登录后即可解锁你的专属内容</text>
  8. </view>
  9. <view class="dvc-benefits">
  10. <view class="dvc-benefit" v-for="(b, i) in benefits" :key="i">
  11. <text class="dvc-dot" :style="{ background: mainColor }"></text>
  12. <text class="dvc-benefit-text">{{ b }}</text>
  13. </view>
  14. </view>
  15. <view class="dvc-actions">
  16. <button class="dvc-btn-primary" :style="{ background: mainColor }" @click="onLogin">{{ ctaText }}</button>
  17. <button
  18. v-if="secondaryText"
  19. class="dvc-btn-secondary"
  20. :style="{ color: mainColor, borderColor: mainColor }"
  21. @click="onSecondary">{{ secondaryText }}</button>
  22. </view>
  23. </view>
  24. <!-- 维度专属预览占位(登录后展示真实数据) -->
  25. <view class="dvc-preview" v-if="previewText">
  26. <text class="dvc-preview-icon">{{ previewIcon }}</text>
  27. <text class="dvc-preview-text">{{ previewText }}</text>
  28. </view>
  29. </view>
  30. </template>
  31. <script>
  32. import { BrandColors } from '../utils/brand-colors.js'
  33. /**
  34. * 维度游客价值卡 —— 五维主页面登录前统一复用
  35. *
  36. * 维度色严格对齐 uni.scss 五维令牌(v4.0):
  37. * 身 body #FF8C42 心 mind #FF6B9D
  38. * 智 wisdom #6366F1 行 action #10B981 富 wealth #F59E0B
  39. * 此处用显式 hex(与令牌值一致)而非 var(--x),确保 mp-weixin 运行时稳定渲染。
  40. *
  41. * 登录行为复用全局 mixin 的 openLoginSheet()(main.js 已全局注册)。
  42. */
  43. var DIM_TOKENS = {
  44. body: { main: BrandColors.body, soft: 'rgba(255, 140, 66, 0.15)', icon: '🌿' },
  45. mind: { main: BrandColors.mind, soft: 'rgba(255, 107, 157, 0.15)', icon: '🔥' },
  46. wisdom: { main: BrandColors.wisdom, soft: 'rgba(99, 102, 241, 0.15)', icon: '⚡' },
  47. action: { main: BrandColors.success, soft: 'rgba(16, 185, 129, 0.15)', icon: '🤝' },
  48. wealth: { main: BrandColors.wealth, soft: 'rgba(245, 158, 11, 0.15)', icon: '💧' }
  49. }
  50. export default {
  51. props: {
  52. /** 维度编码:body | mind | wisdom | action | wealth */
  53. dimCode: { type: String, default: 'body' },
  54. /** 卡片标题 */
  55. cardTitle: { type: String, default: '登录后查看专属内容' },
  56. /** 价值收益列表(2–3 条) */
  57. benefits: {
  58. type: Array,
  59. default: function() { return [] }
  60. },
  61. /** 主登录按钮文案 */
  62. ctaText: { type: String, default: '立即登录' },
  63. /** 次级动作文案(可选) */
  64. secondaryText: { type: String, default: '' },
  65. /** 次级动作跳转地址(可选);留空则 emit('secondary') */
  66. secondaryUrl: { type: String, default: '' },
  67. /** 维度专属预览占位文案(可选);留空则不渲染预览块 */
  68. previewText: { type: String, default: '' }
  69. },
  70. computed: {
  71. token: function() {
  72. return DIM_TOKENS[this.dimCode] || DIM_TOKENS.body
  73. },
  74. mainColor: function() { return this.token.main },
  75. softColor: function() { return this.token.soft },
  76. previewIcon: function() { return this.token.icon }
  77. },
  78. methods: {
  79. onLogin: function() {
  80. // 全局 mixin 提供 openLoginSheet;极端情况下回退整页登录
  81. if (typeof this.openLoginSheet === 'function') {
  82. this.openLoginSheet()
  83. } else {
  84. uni.navigateTo({ url: '/pages/login/login' })
  85. }
  86. },
  87. onSecondary: function() {
  88. if (this.secondaryUrl) {
  89. uni.navigateTo({ url: this.secondaryUrl })
  90. } else {
  91. this.$emit('secondary')
  92. }
  93. }
  94. }
  95. }
  96. </script>
  97. <style scoped lang="scss">
  98. .dvc {
  99. margin: 12rpx 30rpx 0;
  100. }
  101. .dvc-card {
  102. border-radius: 24rpx;
  103. padding: 32rpx 28rpx;
  104. }
  105. .dvc-head {
  106. margin-bottom: 22rpx;
  107. }
  108. .dvc-title {
  109. font-size: 30rpx;
  110. font-weight: 600;
  111. color: $facade-text-gray-800;
  112. display: block;
  113. line-height: 1.4;
  114. }
  115. .dvc-sub {
  116. font-size: 22rpx;
  117. color: $facade-text-muted;
  118. margin-top: 6rpx;
  119. display: block;
  120. }
  121. .dvc-benefits {
  122. margin-bottom: 26rpx;
  123. }
  124. .dvc-benefit {
  125. display: flex;
  126. flex-direction: row;
  127. align-items: center;
  128. margin-bottom: 16rpx;
  129. }
  130. .dvc-dot {
  131. width: 12rpx;
  132. height: 12rpx;
  133. border-radius: 50%;
  134. margin-right: 16rpx;
  135. flex-shrink: 0;
  136. }
  137. .dvc-benefit-text {
  138. font-size: 26rpx;
  139. color: $facade-text-strong;
  140. line-height: 1.5;
  141. }
  142. .dvc-actions {
  143. display: flex;
  144. flex-direction: row;
  145. gap: 20rpx;
  146. }
  147. .dvc-btn-primary {
  148. flex: 1;
  149. height: 88rpx;
  150. line-height: 88rpx;
  151. border-radius: 44rpx;
  152. color: $app-surface;
  153. font-size: 28rpx;
  154. font-weight: 600;
  155. border: none;
  156. padding: 0;
  157. }
  158. .dvc-btn-primary:active { opacity: 0.85; }
  159. .dvc-btn-secondary {
  160. flex: 1;
  161. height: 88rpx;
  162. line-height: 88rpx;
  163. border-radius: 44rpx;
  164. background: $app-surface;
  165. font-size: 28rpx;
  166. font-weight: 500;
  167. border: 2rpx solid;
  168. padding: 0;
  169. }
  170. .dvc-btn-secondary:active { opacity: 0.7; }
  171. .dvc-preview {
  172. margin-top: 24rpx;
  173. background: $app-surface;
  174. border: 1rpx dashed $facade-gray-200;
  175. border-radius: 20rpx;
  176. padding: 40rpx 28rpx;
  177. display: flex;
  178. flex-direction: column;
  179. align-items: center;
  180. }
  181. .dvc-preview-icon {
  182. font-size: 44rpx;
  183. margin-bottom: 14rpx;
  184. }
  185. .dvc-preview-text {
  186. font-size: 24rpx;
  187. color: $facade-text-muted;
  188. text-align: center;
  189. line-height: 1.6;
  190. }
  191. </style>