From 6f76be4da441c30b550ade15bc1f9eb3e9e6a1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Mon, 11 Aug 2025 18:15:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor(components):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=92=8C=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 CouponCard 组件样式,优化主题颜色和布局 - 调整 CouponList 组件样式,使用原生样式替代自定义样式 - 修改 orderConfirm 页面中的地址栏样式 - 更新 QuantitySelector 组件样式,统一数量选择器样式 - 删除 Questions 组件代码 --- src/components/CouponCard.scss | 329 +++++++++++---------------- src/components/CouponCard.tsx | 49 ++-- src/components/CouponList.tsx | 21 +- src/components/QuantitySelector.scss | 3 +- src/components/QuantitySelector.tsx | 8 +- src/components/Questions.tsx | 42 ---- src/shop/orderConfirm/index.scss | 2 +- src/shop/orderConfirm/index.tsx | 63 +++-- src/utils/payment.ts | 2 +- 9 files changed, 226 insertions(+), 293 deletions(-) delete mode 100644 src/components/Questions.tsx diff --git a/src/components/CouponCard.scss b/src/components/CouponCard.scss index 6dd4559..0a759cc 100644 --- a/src/components/CouponCard.scss +++ b/src/components/CouponCard.scss @@ -6,193 +6,173 @@ margin-bottom: 12px; border-radius: 8px; overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); background: #fff; - &--disabled { + &.disabled { opacity: 0.6; } - // 主题颜色 - &--red { - .coupon-card__left { - background: linear-gradient(135deg, #ff6b6b, #ff5252); - } - .coupon-card__btn--receive, - .coupon-card__btn--use { - background: linear-gradient(135deg, #ff6b6b, #ff5252); - color: #fff; - } - } - - &--orange { - .coupon-card__left { - background: linear-gradient(135deg, #ffa726, #ff9800); - } - .coupon-card__btn--receive, - .coupon-card__btn--use { - background: linear-gradient(135deg, #ffa726, #ff9800); - color: #fff; - } - } - - &--blue { - .coupon-card__left { - background: linear-gradient(135deg, #42a5f5, #2196f3); - } - .coupon-card__btn--receive, - .coupon-card__btn--use { - background: linear-gradient(135deg, #42a5f5, #2196f3); - color: #fff; - } - } - - &--purple { - .coupon-card__left { - background: linear-gradient(135deg, #ab47bc, #9c27b0); - } - .coupon-card__btn--receive, - .coupon-card__btn--use { - background: linear-gradient(135deg, #ab47bc, #9c27b0); - color: #fff; - } - } - - &--green { - .coupon-card__left { - background: linear-gradient(135deg, #66bb6a, #4caf50); - } - .coupon-card__btn--receive, - .coupon-card__btn--use { - background: linear-gradient(135deg, #66bb6a, #4caf50); - color: #fff; - } - } - - // 左侧金额区域 - &__left { - flex: 0 0 100px; + .coupon-left { + flex-shrink: 0; + width: 100px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; position: relative; - } - &__amount { - display: flex; - align-items: baseline; - margin-bottom: 4px; - } + &.theme-red { + background: linear-gradient(135deg, #f87171 0%, #ef4444 100%); + } - &__currency { - font-size: 14px; - font-weight: 500; - margin-right: 1px; - } + &.theme-orange { + background: linear-gradient(135deg, #fb923c 0%, #f97316 100%); + } - &__value { - font-size: 28px; - font-weight: bold; - line-height: 1; - } + &.theme-blue { + background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%); + } - &__condition { - font-size: 11px; - opacity: 0.9; - margin-top: 2px; - } + &.theme-purple { + background: linear-gradient(135deg, #a78bfa 0%, #8b5cf6 100%); + } - // 分割线区域 - &__divider { - flex: 0 0 2px; - position: relative; - background: #f0f0f0; - } + &.theme-green { + background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); + } - &__divider-line { - width: 100%; - height: 100%; - background: repeating-linear-gradient( - to bottom, - transparent 0px, - transparent 4px, - #ddd 4px, - #ddd 8px - ); + .amount-wrapper { + display: flex; + align-items: baseline; + margin-bottom: 4px; + + .currency { + font-size: 14px; + font-weight: 500; + margin-right: 2px; + } + + .amount { + font-size: 30px; + font-weight: bold; + line-height: 1; + } + } + + .condition { + font-size: 12px; + opacity: 0.9; + margin-top: 2px; + } } - &__circle { - position: absolute; - width: 16px; - height: 16px; + .coupon-divider { + flex-shrink: 0; + width: 2px; + position: relative; background: #f5f5f5; - border-radius: 50%; - left: 50%; - transform: translateX(-50%); - &--top { + .divider-line { + width: 100%; + height: 100%; + background: repeating-linear-gradient( + to bottom, + transparent 0px, + transparent 4px, + #ddd 4px, + #ddd 8px + ); + } + + .divider-circle-top { + position: absolute; + width: 16px; + height: 16px; + background: #f5f5f5; + border-radius: 50%; top: -8px; + left: -7px; } - &--bottom { + .divider-circle-bottom { + position: absolute; + width: 16px; + height: 16px; + background: #f5f5f5; + border-radius: 50%; bottom: -8px; + left: -7px; } } - // 右侧信息区域 - &__right { + .coupon-right { flex: 1; display: flex; flex-direction: column; justify-content: space-between; padding: 12px; - } - &__info { - flex: 1; - } + .coupon-info { + flex: 1; - &__title { - font-size: 14px; - font-weight: 600; - color: #333; - margin-bottom: 4px; - } - - &__validity { - font-size: 11px; - color: #999; - } + .coupon-title { + font-size: 14px; + font-weight: 600; + color: #1f2937; + margin-bottom: 4px; + } - &__action { - display: flex; - justify-content: flex-end; - align-items: center; - } - - &__btn { - min-width: 50px; - height: 24px; - border-radius: 12px; - font-size: 11px; - border: none; - - &--receive, - &--use { - color: #fff; + .coupon-validity { + font-size: 12px; + color: #6b7280; + } } - } - &__status { - font-size: 12px; - color: #999; - padding: 4px 8px; + .coupon-actions { + display: flex; + justify-content: flex-end; + align-items: center; + + .coupon-btn { + min-width: 48px; + height: 24px; + border-radius: 12px; + font-size: 12px; + border: none; + color: #fff; + + &.theme-red { + background: linear-gradient(135deg, #f87171 0%, #ef4444 100%); + } + + &.theme-orange { + background: linear-gradient(135deg, #fb923c 0%, #f97316 100%); + } + + &.theme-blue { + background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%); + } + + &.theme-purple { + background: linear-gradient(135deg, #a78bfa 0%, #8b5cf6 100%); + } + + &.theme-green { + background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); + } + } + + .status-text { + font-size: 12px; + color: #6b7280; + padding: 4px 8px; + } + } } - // 状态遮罩 - &__mask { + .status-overlay { position: absolute; top: 0; left: 0; @@ -202,52 +182,15 @@ display: flex; align-items: center; justify-content: center; - z-index: 1; - } - - &__mask-text { - background: rgba(0, 0, 0, 0.6); - color: #fff; - padding: 4px 12px; - border-radius: 12px; - font-size: 14px; - font-weight: 500; - } -} - -// 优惠券列表容器 -.coupon-list { - padding: 16px; - - &__title { - font-size: 18px; - font-weight: 600; - color: #333; - margin-bottom: 16px; - } + z-index: 10; - &__empty { - text-align: center; - padding: 40px 20px; - color: #999; - font-size: 14px; - } -} - -// 优惠券横向滚动容器 -.coupon-scroll { - display: flex; - padding: 16px; - gap: 8px; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - - &::-webkit-scrollbar { - display: none; - } - - .coupon-card { - flex: 0 0 240px; - margin-bottom: 0; + .status-badge { + background: rgba(0, 0, 0, 0.6); + color: #fff; + padding: 4px 12px; + border-radius: 12px; + font-size: 14px; + font-weight: 500; + } } } diff --git a/src/components/CouponCard.tsx b/src/components/CouponCard.tsx index 6cca271..d06f903 100644 --- a/src/components/CouponCard.tsx +++ b/src/components/CouponCard.tsx @@ -44,7 +44,12 @@ const CouponCard: React.FC = ({ onUse, theme = 'red' }) => { + // 获取主题颜色类名 + const getThemeClass = () => { + return `theme-${theme}` + } // 格式化优惠券金额显示 + // @ts-ignore const formatAmount = () => { switch (type) { case 1: // 满减券 @@ -96,42 +101,44 @@ const CouponCard: React.FC = ({ return '' } + const themeClass = getThemeClass() + return ( - + {/* 左侧金额区域 */} - - - ¥ - {amount} + + + ¥ + {amount} - + {getConditionText()} {/* 中间分割线 */} - - - - + + + + {/* 右侧信息区域 */} - - - + + + {title || (type === 1 ? '满减券' : type === 2 ? '折扣券' : '免费券')} - + 有效期:{getValidityText()} {/* 按钮区域 */} - + {showReceiveBtn && status === 0 && ( )} {status !== 0 && ( - + {getStatusText()} )} @@ -157,8 +164,10 @@ const CouponCard: React.FC = ({ {/* 状态遮罩 */} {status !== 0 && ( - - {getStatusText()} + + + {getStatusText()} + )} diff --git a/src/components/CouponList.tsx b/src/components/CouponList.tsx index 3e5d02b..ebfb0ea 100644 --- a/src/components/CouponList.tsx +++ b/src/components/CouponList.tsx @@ -1,7 +1,6 @@ import React from 'react' import { View, ScrollView } from '@tarojs/components' import CouponCard, { CouponCardProps } from './CouponCard' -import './CouponCard.scss' export interface CouponListProps { /** 优惠券列表数据 */ @@ -33,14 +32,14 @@ const CouponList: React.FC = ({ // 垂直布局 if (layout === 'vertical') { return ( - + {title && ( - {title} + {title} )} - + {coupons.length === 0 ? ( showEmpty && ( - + {emptyText} ) @@ -62,26 +61,30 @@ const CouponList: React.FC = ({ return ( {title && ( - + {title} )} - + {coupons.length === 0 ? ( showEmpty && ( - + {emptyText} ) ) : ( {coupons.map((coupon, index) => ( handleCouponClick(coupon, index)} > diff --git a/src/components/QuantitySelector.scss b/src/components/QuantitySelector.scss index 072f6d6..7204172 100644 --- a/src/components/QuantitySelector.scss +++ b/src/components/QuantitySelector.scss @@ -21,7 +21,7 @@ background: #f8f8f8; color: #666; transition: all 0.2s ease; - + &:active { background: #e5e5e5; } @@ -54,7 +54,6 @@ } &__stock-text { - font-size: 12px; color: #999; } diff --git a/src/components/QuantitySelector.tsx b/src/components/QuantitySelector.tsx index 065e3c0..9e42455 100644 --- a/src/components/QuantitySelector.tsx +++ b/src/components/QuantitySelector.tsx @@ -59,11 +59,11 @@ const QuantitySelector: React.FC = ({ > - + {value} - + - + {showStock && stock !== undefined && ( - + 库存 {stock} 件 diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx deleted file mode 100644 index a665bd9..0000000 --- a/src/components/Questions.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import {useEffect, useState} from "react"; -import {pageHjmQuestions} from "@/api/hjm/hjmQuestions"; -import {HjmQuestions} from "@/api/hjm/hjmQuestions/model"; - -/** - * 文章终极列表 - * @constructor - */ -const Questions = () => { - const [list, setList] = useState([]) - - const reload = () => { - pageHjmQuestions({}).then(res => { - if (res?.list) { - setList(res?.list) - } - }) - } - - useEffect(() => { - reload() - }, []) - - return ( -
-
-
- { - list.map((item, index) => { - return ( -
-
{item.question}
-
- ) - }) - } -
-
-
- ) -} -export default Questions diff --git a/src/shop/orderConfirm/index.scss b/src/shop/orderConfirm/index.scss index 87b5288..20c489f 100644 --- a/src/shop/orderConfirm/index.scss +++ b/src/shop/orderConfirm/index.scss @@ -41,7 +41,7 @@ } .address-bottom-line{ width: 100%; - border-radius: 24rpx 24rpx 0 0; + border-radius: 12rpx 12rpx 0 0; background: #fff; padding: 26rpx 49rpx 0 34rpx; position: relative; diff --git a/src/shop/orderConfirm/index.tsx b/src/shop/orderConfirm/index.tsx index 39e6b64..ace5a61 100644 --- a/src/shop/orderConfirm/index.tsx +++ b/src/shop/orderConfirm/index.tsx @@ -8,7 +8,6 @@ import { Space, ActionSheet, Popup, - Toast, InputNumber, ConfigProvider } from '@nutui/nutui-react-taro' @@ -143,19 +142,28 @@ const OrderConfirm = () => { // 检查是否满足使用条件 if (coupon.minAmount && total < coupon.minAmount) { - Toast.show(`需满${coupon.minAmount}元才能使用此优惠券`) + Taro.showToast({ + title: `需满${coupon.minAmount}元才能使用此优惠券`, + icon: 'none' + }) return } setSelectedCoupon(coupon) setCouponVisible(false) - Toast.show('优惠券选择成功') + Taro.showToast({ + title: '优惠券选择成功', + icon: 'success' + }) } // 取消选择优惠券 const handleCouponCancel = () => { setSelectedCoupon(null) - Toast.show('已取消使用优惠券') + Taro.showToast({ + title: '已取消使用优惠券', + icon: 'success' + }) } /** @@ -167,18 +175,27 @@ const OrderConfirm = () => { // 基础校验 if (!address) { - Toast.show('请选择收货地址') + Taro.showToast({ + title: '请选择收货地址', + icon: 'error' + }) return; } if (!payment) { - Toast.show('请选择支付方式') + Taro.showToast({ + title: '请选择支付方式', + icon: 'error' + }) return; } // 库存校验 if (goods.stock !== undefined && quantity > goods.stock) { - Toast.show('商品库存不足') + Taro.showToast({ + title: '商品库存不足', + icon: 'error' + }) return; } @@ -191,8 +208,7 @@ const OrderConfirm = () => { comments: goods.name, deliveryType: 0, buyerRemarks: orderRemark, - couponId: selectedCoupon ? selectedCoupon.amount : undefined, - couponDiscount: getCouponDiscount() + couponId: selectedCoupon ? selectedCoupon.amount : undefined } ); @@ -202,10 +218,16 @@ const OrderConfirm = () => { // 执行支付 await PaymentHandler.pay(orderData, paymentType); - Toast.show('支付成功') + Taro.showToast({ + title: '支付成功', + icon: 'success' + }) } catch (error) { console.error('支付失败:', error) - Toast.show('支付失败,请重试') + Taro.showToast({ + title: '支付失败,请重试', + icon: 'error' + }) } finally { setPayLoading(false) } @@ -217,17 +239,16 @@ const OrderConfirm = () => { setLoading(true) setError('') - // 并行加载商品信息和其他数据 - const promises = [] - + // 分别加载数据,避免类型推断问题 + let goodsRes: ShopGoods | null = null if (goodsId) { - promises.push(getShopGoods(Number(goodsId))) + goodsRes = await getShopGoods(Number(goodsId)) } - promises.push(listShopUserAddress({isDefault: true})) - promises.push(selectPayment({})) - - const [goodsRes, addressRes, paymentRes] = await Promise.all(promises) + const [addressRes, paymentRes] = await Promise.all([ + listShopUserAddress({isDefault: true}), + selectPayment({}) + ]) // 设置商品信息 if (goodsRes) { @@ -424,7 +445,7 @@ const OrderConfirm = () => { > - 选择优惠券 + 选择优惠券