CouponGuide.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <template>
  2. <div class="guide-card wide">
  3. <div class="guide-illustration" style="background: linear-gradient(135deg, #e87722 0%, #f9ca24 100%);">
  4. <div class="illus-bubble bubble-1">🎫</div>
  5. <div class="illus-bubble bubble-2">🎁</div>
  6. <div class="illus-center">🎟️</div>
  7. </div>
  8. <div class="guide-body">
  9. <div class="guide-badge">Step 8</div>
  10. <h2 class="guide-title">个人中心 — 礼品券兑换</h2>
  11. <p class="guide-desc">在「我的礼品券」Tab 管理你的礼品券,支持三种状态:</p>
  12. <!-- 状态说明 -->
  13. <div class="tab-list">
  14. <div class="tab-item" v-for="item in statusList" :key="item.id">
  15. <div class="tab-num">{{ item.icon }}</div>
  16. <div class="tab-info">
  17. <div class="tab-title">{{ item.title }}</div>
  18. <div class="tab-desc">{{ item.desc }}</div>
  19. </div>
  20. </div>
  21. </div>
  22. <!-- 兑换流程 -->
  23. <div class="redeem-flow">
  24. <span class="flow-tip">🎫 礼品券兑换路径:</span>
  25. <div class="flow-steps">
  26. <span v-for="(step, i) in flowSteps" :key="i" class="flow-step-wrap">
  27. <span class="flow-step">{{ step }}</span>
  28. <span v-if="i < flowSteps.length - 1" class="flow-arrow">→</span>
  29. </span>
  30. </div>
  31. </div>
  32. </div>
  33. <div class="guide-footer">
  34. <button class="btn-primary" @click="handleGoCoupon">
  35. <span>🎫</span> 查看礼品券
  36. </button>
  37. <button class="btn-prev" v-if="!isFirst" @click="$emit('prev')">
  38. ← 上一步
  39. </button>
  40. </div>
  41. </div>
  42. </template>
  43. <script>
  44. import { setTab } from '@/utils/auth'
  45. export default {
  46. name: 'CouponGuide',
  47. props: {
  48. isLast: { type: Boolean, default: false },
  49. isFirst: { type: Boolean, default: false },
  50. isReplay: { type: Boolean, default: false },
  51. },
  52. data() {
  53. return {
  54. statusList: [
  55. { id: 1, icon: '🟢', title: '去使用', desc: '礼品券未使用,点击「去使用」即可兑换' },
  56. { id: 2, icon: '⚪', title: '已使用', desc: '礼品券已完成兑换' },
  57. { id: 3, icon: '🔴', title: '已超期', desc: '礼品券已过期,无法使用' },
  58. ],
  59. flowSteps: ['选择商品', '确认订单', '礼品券抵扣', '兑换成功'],
  60. }
  61. },
  62. methods: {
  63. handleGoCoupon() {
  64. setTab('welfare')
  65. // 先跳首页再跳 myCenter,确保组件重新 created 读取 Cookie
  66. this.$router.push('/home').then(() => {
  67. this.$router.push('/myCenter')
  68. })
  69. setTimeout(() => this.$emit('next'), 800)
  70. },
  71. },
  72. }
  73. </script>
  74. <style scoped>
  75. .guide-card {
  76. width: 440px;
  77. max-width: 90vw;
  78. background: #fff;
  79. border-radius: 20px;
  80. overflow: hidden;
  81. box-shadow: 0 20px 60px rgba(0,0,0,0.25);
  82. animation: cardFloat 0.5s ease-out;
  83. }
  84. .guide-card.wide { width: 500px; }
  85. @keyframes cardFloat {
  86. from { opacity: 0; transform: translateY(30px) scale(0.95); }
  87. to { opacity: 1; transform: translateY(0) scale(1); }
  88. }
  89. .guide-illustration {
  90. position: relative;
  91. height: 130px;
  92. display: flex;
  93. align-items: center;
  94. justify-content: center;
  95. overflow: hidden;
  96. }
  97. .illus-center { font-size: 52px; z-index: 2; }
  98. .illus-bubble {
  99. position: absolute;
  100. font-size: 22px;
  101. animation: bubbleFloat 4s ease-in-out infinite;
  102. }
  103. .bubble-1 { top: 18px; left: 28px; animation-delay: 0s; }
  104. .bubble-2 { bottom: 18px; right: 28px; animation-delay: 2s; }
  105. @keyframes bubbleFloat {
  106. 0%, 100% { transform: translateY(0); }
  107. 50% { transform: translateY(-8px); }
  108. }
  109. .guide-body { padding: 20px 28px 14px; }
  110. .guide-badge {
  111. display: inline-block;
  112. padding: 3px 12px;
  113. font-size: 12px;
  114. font-weight: 600;
  115. color: #e87722;
  116. background: #fff4e8;
  117. border-radius: 12px;
  118. margin-bottom: 10px;
  119. }
  120. .guide-title {
  121. font-size: 18px;
  122. font-weight: 700;
  123. color: #1d2129;
  124. margin: 0 0 6px;
  125. }
  126. .guide-desc {
  127. font-size: 13px;
  128. line-height: 1.6;
  129. color: #86909c;
  130. margin: 0 0 14px;
  131. }
  132. .tab-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
  133. .tab-item {
  134. display: flex;
  135. align-items: center;
  136. gap: 10px;
  137. padding: 10px 12px;
  138. background: #f7f9fc;
  139. border-radius: 10px;
  140. transition: all 0.25s;
  141. }
  142. .tab-item:hover { background: #fff4e8; }
  143. .tab-num {
  144. width: 28px;
  145. height: 28px;
  146. line-height: 28px;
  147. text-align: center;
  148. font-size: 16px;
  149. flex-shrink: 0;
  150. }
  151. .tab-info { flex: 1; }
  152. .tab-title { font-size: 13px; font-weight: 600; color: #1d2129; }
  153. .tab-desc { font-size: 12px; color: #86909c; margin-top: 2px; }
  154. .redeem-flow {
  155. padding: 10px 12px;
  156. background: linear-gradient(135deg, #fff9f0, #fff4e0);
  157. border-radius: 10px;
  158. border-left: 3px solid #e87722;
  159. }
  160. .flow-tip { font-size: 12px; color: #e87722; font-weight: 600; display: block; margin-bottom: 6px; }
  161. .flow-steps { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
  162. .flow-step-wrap { display: flex; align-items: center; gap: 4px; }
  163. .flow-step {
  164. padding: 3px 8px;
  165. background: #fff;
  166. border: 1px solid #e87722;
  167. border-radius: 6px;
  168. font-size: 11px;
  169. color: #e87722;
  170. font-weight: 500;
  171. }
  172. .flow-arrow { font-size: 12px; color: #e87722; }
  173. .guide-footer {
  174. padding: 14px 28px 22px;
  175. display: flex;
  176. flex-direction: column;
  177. gap: 10px;
  178. }
  179. .btn-primary {
  180. display: flex;
  181. align-items: center;
  182. justify-content: center;
  183. gap: 8px;
  184. height: 44px;
  185. font-size: 15px;
  186. font-weight: 600;
  187. color: #fff;
  188. background: linear-gradient(135deg, #e87722, #f9ca24);
  189. border: none;
  190. border-radius: 22px;
  191. cursor: pointer;
  192. transition: all 0.3s;
  193. box-shadow: 0 4px 14px rgba(232,119,34,0.3);
  194. }
  195. .btn-primary:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(232,119,34,0.45); }
  196. .btn-prev {
  197. height: 40px;
  198. font-size: 14px;
  199. font-weight: 500;
  200. color: #86909c;
  201. background: #f7f9fc;
  202. border: none;
  203. border-radius: 20px;
  204. cursor: pointer;
  205. transition: all 0.25s;
  206. }
  207. .btn-prev:hover { color: #4e5969; background: #eef1f6; }
  208. </style>