RulesModal.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <template>
  2. <!-- 使用规则弹窗 -->
  3. <BasicModal type="bottom" v-model:open="getOpen" :is-mack="true">
  4. <view class="rules-modal">
  5. <!-- 标题栏 -->
  6. <view class="rules-modal__header">
  7. <text class="header-title">使用规则</text>
  8. <view class="close-btn" @click="handleClose">
  9. <view class="close-icon"></view>
  10. </view>
  11. </view>
  12. <!-- 优惠券卡片 - 与列表页样式一致 -->
  13. <view class="coupon-card-wrapper">
  14. <view class="coupon-card">
  15. <image :src="getFileUrl('img/personal/coupon.png')" mode="widthFix" class="coupon-card-bg"></image>
  16. <image :src="getFileUrl('img/personal/couponLeft.png')" mode="heightFix" class="coupon-card-bgLeft"></image>
  17. <view class="coupon-card-content">
  18. <!-- 左侧金额区域 -->
  19. <view class="coupon-card__left">
  20. <view class="amount-wrapper">
  21. <text class="amount-number">{{ couponData?.amount || 0 }}</text>
  22. <text class="amount-unit">元</text>
  23. </view>
  24. <text class="condition-text">满{{ couponData?.minAmount || 0 }}可用</text>
  25. </view>
  26. <!-- 右侧信息区域 -->
  27. <view class="coupon-card__right">
  28. <view class="coupon-info">
  29. <text class="coupon-name">{{ couponData?.name || '6元通用优惠券' }}</text>
  30. <text class="coupon-expire">{{ couponData?.expireDate || '' }}到期</text>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. </view>
  36. <!-- 规则详情 -->
  37. <view class="rules-content">
  38. <view class="rules-item">
  39. <text class="rules-label">有效期</text>
  40. <text class="rules-value">{{ couponData?.validDays || 90 }}天</text>
  41. </view>
  42. <view class="rules-item">
  43. <text class="rules-label">补充说明</text>
  44. <text class="rules-value">{{ couponData?.description || '周一、周五不可用' }}</text>
  45. </view>
  46. </view>
  47. <!-- 底部按钮 -->
  48. <view class="rules-modal__footer">
  49. <view class="use-btn" hover-class="hover-active" @click="handleUse">
  50. 去使用
  51. </view>
  52. </view>
  53. </view>
  54. </BasicModal>
  55. </template>
  56. <script setup>
  57. import { computed } from 'vue';
  58. import BasicModal from '@/components/Modal/BasicModal.vue';
  59. import { getFileUrl } from '@/utils/file.js';
  60. const props = defineProps({
  61. open: {
  62. type: Boolean,
  63. default: false
  64. },
  65. couponData: {
  66. type: Object,
  67. default: () => ({
  68. amount: 6,
  69. minAmount: 66,
  70. name: '6元通用优惠券',
  71. expireDate: '2025/07/12',
  72. validDays: 90,
  73. description: '周一、周五不可用'
  74. })
  75. }
  76. });
  77. const emit = defineEmits(['update:open', 'use']);
  78. const getOpen = computed({
  79. get: () => props.open,
  80. set: (val) => emit('update:open', val)
  81. });
  82. // 关闭弹窗
  83. const handleClose = () => {
  84. getOpen.value = false;
  85. };
  86. // 使用优惠券
  87. const handleUse = () => {
  88. emit('use', props.couponData);
  89. getOpen.value = false;
  90. };
  91. </script>
  92. <style lang="scss" scoped>
  93. .rules-modal {
  94. width: 100%;
  95. background: #FFFFFF;
  96. border-radius: 24rpx 24rpx 0 0;
  97. padding: 32rpx 30rpx;
  98. padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  99. box-sizing: border-box;
  100. // 标题栏
  101. &__header {
  102. display: flex;
  103. align-items: center;
  104. justify-content: center;
  105. margin-bottom: 32rpx;
  106. position: relative;
  107. .header-title {
  108. font-size: 36rpx;
  109. font-weight: bold;
  110. color: #151515;
  111. }
  112. .close-btn {
  113. position: absolute;
  114. right: 0;
  115. top: 50%;
  116. transform: translateY(-50%);
  117. width: 48rpx;
  118. height: 48rpx;
  119. display: flex;
  120. align-items: center;
  121. justify-content: center;
  122. .close-icon {
  123. width: 28rpx;
  124. height: 28rpx;
  125. position: relative;
  126. &::before,
  127. &::after {
  128. content: '';
  129. position: absolute;
  130. width: 28rpx;
  131. height: 2rpx;
  132. background: #999999;
  133. top: 50%;
  134. left: 50%;
  135. transform-origin: center;
  136. }
  137. &::before {
  138. transform: translate(-50%, -50%) rotate(45deg);
  139. }
  140. &::after {
  141. transform: translate(-50%, -50%) rotate(-45deg);
  142. }
  143. }
  144. }
  145. }
  146. // 优惠券卡片容器
  147. .coupon-card-wrapper {
  148. margin-bottom: 32rpx;
  149. }
  150. // 优惠券卡片样式 - 与列表页完全一致
  151. .coupon-card {
  152. display: flex;
  153. align-items: center;
  154. overflow: hidden;
  155. position: relative;
  156. box-sizing: border-box;
  157. .coupon-card-bg {
  158. position: absolute;
  159. top: 0;
  160. left: 0;
  161. width: 100%;
  162. height: 100%;
  163. z-index: 1;
  164. }
  165. .coupon-card-bgLeft {
  166. position: absolute;
  167. top: 0;
  168. left: 0;
  169. width: auto;
  170. height: 190rpx;
  171. z-index: 1;
  172. }
  173. .coupon-card-content {
  174. position: relative;
  175. z-index: 3;
  176. display: flex;
  177. align-items: center;
  178. width: 100%;
  179. height: 200rpx;
  180. }
  181. &__left {
  182. width: 200rpx;
  183. padding: 32rpx 0;
  184. display: flex;
  185. flex-direction: column;
  186. align-items: center;
  187. justify-content: center;
  188. .amount-wrapper {
  189. display: flex;
  190. align-items: baseline;
  191. margin-bottom: 8rpx;
  192. .amount-number {
  193. font-size: 64rpx;
  194. font-weight: bold;
  195. color: #F47D1F;
  196. line-height: 1;
  197. }
  198. .amount-unit {
  199. font-size: 28rpx;
  200. color: #F47D1F;
  201. margin-left: 4rpx;
  202. }
  203. }
  204. .condition-text {
  205. font-size: 22rpx;
  206. color: #F47D1F;
  207. }
  208. }
  209. &__right {
  210. flex: 1;
  211. display: flex;
  212. align-items: center;
  213. justify-content: space-between;
  214. padding: 32rpx 24rpx;
  215. .coupon-info {
  216. flex: 1;
  217. display: flex;
  218. flex-direction: column;
  219. .coupon-name {
  220. font-size: 28rpx;
  221. font-weight: bold;
  222. color: #151515;
  223. margin-bottom: 12rpx;
  224. }
  225. .coupon-expire {
  226. font-size: 22rpx;
  227. color: #999999;
  228. }
  229. }
  230. }
  231. }
  232. // 规则详情
  233. .rules-content {
  234. margin-bottom: 40rpx;
  235. padding: 0 8rpx;
  236. .rules-item {
  237. display: flex;
  238. align-items: flex-start;
  239. margin-bottom: 20rpx;
  240. font-size: 26rpx;
  241. line-height: 40rpx;
  242. &:last-child {
  243. margin-bottom: 0;
  244. }
  245. .rules-label {
  246. color: #666666;
  247. flex-shrink: 0;
  248. }
  249. .rules-value {
  250. color: #151515;
  251. margin-left: 16rpx;
  252. flex: 1;
  253. }
  254. }
  255. }
  256. // 底部按钮
  257. &__footer {
  258. .use-btn {
  259. width: 100%;
  260. height: 88rpx;
  261. background: linear-gradient(135deg, #FF8A57 0%, #F47D1F 100%);
  262. border-radius: 44rpx;
  263. display: flex;
  264. align-items: center;
  265. justify-content: center;
  266. font-size: 32rpx;
  267. font-weight: bold;
  268. color: #FFFFFF;
  269. letter-spacing: 2rpx;
  270. }
  271. }
  272. }
  273. .hover-active {
  274. opacity: 0.8;
  275. transform: scale(0.98);
  276. transition: all 0.2s;
  277. }
  278. </style>