fix(SkuSelector): 修正价格显示逻辑避免价格错误

- 调整fakeSku中price字段优先使用product.price,确保价格正确显示
- 修改currentPrice计算顺序,使price优先于salePrice,符合实际售价需求
- 统一价格逻辑,避免SKU弹窗和商品详情页价格不一致问题
- 添加注释说明ShopGoods和ShopGoodsSku中price与salePrice的区别及优先级规则
This commit is contained in:
2026-06-27 01:08:04 +08:00
parent 9f1c50b7a4
commit cdab04de21
6 changed files with 32 additions and 83 deletions

View File

@@ -3,7 +3,16 @@
## SKU选择器价格显示错误修复 ## SKU选择器价格显示错误修复
- **文件**: `src/components/business/SkuSelector/index.tsx` - **文件**: `src/components/business/SkuSelector/index.tsx`
- **问题**: 商品详情页价格显示 ¥1019但点击"立即购买"后SKU弹窗显示 ¥2519 - **问题**: 商品详情页价格显示 ¥1019但点击"立即购买"后SKU弹窗显示 ¥2519
- **根因**: `currentPrice` 计算式中 `salePrice` 优先级高于 `price`。ShopGoods 模型中 `price`=实际售价(1019)`salePrice`=市场/原价(2519)。当 SKU 未选中时回退到 product 级别,错误地优先取了 salePrice - **根因**: `currentPrice` 计算式中 `salePrice` 优先级高于 `price`。ShopGoods 模型中 `price`=实际售价(1019)`salePrice`=市场/原价(2519)
- **修复**: - **修复**:
1. 第190行: `currentPrice` 优先级改为 `selectedSku?.price || selectedSku?.salePrice || product?.price || product?.salePrice` 1. 第190行: `currentPrice` 优先级改为 `price` 优先于 `salePrice`
2. 第160行: 单规格 fakeSku 的 price 字段同样修正`product.price || product.salePrice` 2. 第160行: 单规格 fakeSku 的 price 字段同样修正
## 确认订单页:货到付款 → 货到付款
- **文件**: `src/pages/shop/checkout.tsx`
- **改动内容**:
1. 支付方式名称:货到付款 → 货到付款,图标"余"→"货",副文案改为"商品送达后付款"
2. 移除用户余额加载逻辑loadUserBalance、userBalance、loadingBalance 状态)
3. 移除余额不足校验和充值引导弹窗
4. payType=0 改为货到付款:提交后直接创建订单并跳转,不走在线支付流程
5. 清理未使用的导入payByBalance、getUserBalance、repairOrder

View File

@@ -11,7 +11,7 @@ interface PayModalProps {
const PAY_TYPES = [ const PAY_TYPES = [
{ id: 1, name: '微信支付', desc: '推荐使用', icon: 'pay-wechat' }, { id: 1, name: '微信支付', desc: '推荐使用', icon: 'pay-wechat' },
{ id: 0, name: '余额支付', desc: '使用账户余额', icon: 'pay-balance' }, { id: 0, name: '货到付款', desc: '使用账户余额', icon: 'pay-balance' },
] ]
const PayModal: React.FC<PayModalProps> = ({ visible, amount, onClose, onConfirm }) => { const PayModal: React.FC<PayModalProps> = ({ visible, amount, onClose, onConfirm }) => {

View File

@@ -36,7 +36,7 @@ const helpData: HelpCategory[] = [
title: '支付与退款', title: '支付与退款',
icon: '💰', icon: '💰',
questions: [ questions: [
{ id: 201, title: '支持哪些支付方式?', content: '我们支持微信支付、支付宝支付(如有)、余额支付、积分抵扣等多种支付方式。' }, { id: 201, title: '支持哪些支付方式?', content: '我们支持微信支付、支付宝支付(如有)、货到付款、积分抵扣等多种支付方式。' },
{ id: 202, title: '如何申请退款?', content: '在订单详情页点击"申请退款"按钮,填写退款原因和说明,提交后等待商家审核。' }, { id: 202, title: '如何申请退款?', content: '在订单详情页点击"申请退款"按钮,填写退款原因和说明,提交后等待商家审核。' },
{ id: 203, title: '退款多久到账?', content: '退款审核通过后原路退回您的支付账户。微信支付一般1-3个工作日到账余额支付即时到账。' }, { id: 203, title: '退款多久到账?', content: '退款审核通过后原路退回您的支付账户。微信支付一般1-3个工作日到账余额支付即时到账。' },
] ]

View File

@@ -14,7 +14,7 @@ definePageConfig({
// 支付方式映射 // 支付方式映射
const PAY_TYPE_MAP: Record<number, string> = { const PAY_TYPE_MAP: Record<number, string> = {
0: '余额支付', 0: '货到付款',
1: '微信支付', 1: '微信支付',
2: '会员卡支付', 2: '会员卡支付',
3: '支付宝', 3: '支付宝',

View File

@@ -8,10 +8,8 @@ import { useScrollHeight } from '@/hooks/useScrollHeight'
import { getMyAvailableCoupons } from '@/api/shop/shopUserCoupon' import { getMyAvailableCoupons } from '@/api/shop/shopUserCoupon'
import AddressCard from '@/components/business/AddressCard' import AddressCard from '@/components/business/AddressCard'
import CouponCard from '@/components/business/CouponCard' import CouponCard from '@/components/business/CouponCard'
import { createOrder, repairOrder, type WxPayResult } from '@/api/shop/shopOrder' import { createOrder, type WxPayResult } from '@/api/shop/shopOrder'
import type { ShopOrder } from '@/api/shop/shopOrder/model' import type { ShopOrder } from '@/api/shop/shopOrder/model'
import { payByBalance } from '@/api/system/payment'
import { getUserBalance } from '@/api/system/user'
import { listShopGoods } from '@/api/shop/shopGoods' import { listShopGoods } from '@/api/shop/shopGoods'
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
import type { ShopUserCoupon } from '@/api/shop/shopUserCoupon/model' import type { ShopUserCoupon } from '@/api/shop/shopUserCoupon/model'
@@ -126,9 +124,8 @@ const CheckoutPage: React.FC = () => {
const [rushBuyProducts, setRushBuyProducts] = useState<ShopGoods[]>([]) const [rushBuyProducts, setRushBuyProducts] = useState<ShopGoods[]>([])
// 支付方式相关状态 // 支付方式相关状态
const [payType, setPayType] = useState<number>(1) // 1: 微信支付, 0: 余额支付 // payType: 1=微信支付, 0=货到付款(默认)
const [userBalance, setUserBalance] = useState<string>('0.00') const [payType, setPayType] = useState<number>(0)
const [loadingBalance, setLoadingBalance] = useState(false)
// 从本地存储获取立即购买的数据 // 从本地存储获取立即购买的数据
const buyNowItems = useMemo(() => { const buyNowItems = useMemo(() => {
@@ -183,7 +180,6 @@ const CheckoutPage: React.FC = () => {
useEffect(() => { useEffect(() => {
loadCoupons() loadCoupons()
loadRushBuyProducts() loadRushBuyProducts()
loadUserBalance()
}, []) }, [])
// 每次页面显示时刷新地址(从地址列表选择后返回) // 每次页面显示时刷新地址(从地址列表选择后返回)
@@ -221,21 +217,7 @@ const CheckoutPage: React.FC = () => {
} }
} }
// 加载用户余额 // 加载凑单推荐商品
const loadUserBalance = async () => {
setLoadingBalance(true)
try {
const data = await getUserBalance()
setUserBalance(data?.balance || '0.00')
} catch (e) {
console.error('加载余额失败:', e)
setUserBalance('0.00')
} finally {
setLoadingBalance(false)
}
}
// 选择地址
const handleSelectAddress = () => { const handleSelectAddress = () => {
Taro.navigateTo({ Taro.navigateTo({
url: '/pages/user/address-list?from=checkout', url: '/pages/user/address-list?from=checkout',
@@ -277,23 +259,6 @@ const CheckoutPage: React.FC = () => {
specInfo: item.skuSpec || item.sku?.sku || item.product?.specName, specInfo: item.skuSpec || item.sku?.sku || item.product?.specName,
})) }))
// 检查余额是否足够(如果选择余额支付)
if (payType === 0 && parseFloat(userBalance) < parseFloat(totalPrice)) {
Taro.showModal({
title: '余额不足',
content: `当前余额 ¥${parseFloat(userBalance).toFixed(2)},需要 ¥${totalPrice},是否前往充值?`,
confirmText: '去充值',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
Taro.navigateTo({ url: '/pages/user/recharge' })
}
}
})
setSubmitting(false)
return
}
// 创建订单 // 创建订单
const orderParams: OrderCreateRequest = { const orderParams: OrderCreateRequest = {
goodsItems, goodsItems,
@@ -308,9 +273,12 @@ const CheckoutPage: React.FC = () => {
// 根据支付方式处理 // 根据支付方式处理
if (payType === 0) { if (payType === 0) {
// 余额支付 - res 包含 { orderId, orderNo, payType, payPrice } // 货到付款 — 直接创建订单,无需在线支付
const balanceRes = res as { orderId?: number; orderNo?: string } Taro.showToast({ title: '下单成功', icon: 'success' })
await handleBalancePay(Number(balanceRes.orderId)) setTimeout(() => {
Taro.redirectTo({ url: '/pages/order/list' })
}, 1500)
return
} else { } else {
// 微信支付 - res 是 WxPayResult // 微信支付 - res 是 WxPayResult
await handleWxPay(res as WxPayResult) await handleWxPay(res as WxPayResult)
@@ -353,23 +321,6 @@ const CheckoutPage: React.FC = () => {
}) })
} }
// 余额支付
const handleBalancePay = async (orderId: number | string) => {
try {
await payByBalance({ orderId: Number(orderId) })
// 余额支付成功后,修复订单支付状态
try {
await repairOrder({ orderId: Number(orderId), payStatus: true } as Partial<ShopOrder>)
} catch {
// 修复失败不影响支付流程
}
// 刷新余额
loadUserBalance()
} catch (err: any) {
throw new Error(err.message || '余额支付失败')
}
}
// 安全的数字格式化 // 安全的数字格式化
const formatPrice = (price: number | string): string => { const formatPrice = (price: number | string): string => {
const num = typeof price === 'string' ? parseFloat(price) : price const num = typeof price === 'string' ? parseFloat(price) : price
@@ -540,20 +491,18 @@ const CheckoutPage: React.FC = () => {
{/* </View>*/} {/* </View>*/}
{/*</View>*/} {/*</View>*/}
{/* 余额支付 */} {/* 货到付款 */}
<View <View
className='flex items-center py-3 px-2 rounded-lg' className='flex items-center py-3 px-2 rounded-lg'
style={{ backgroundColor: payType === 0 ? '#f0fdf4' : '#f9fafb' }} style={{ backgroundColor: payType === 0 ? '#f0fdf4' : '#f9fafb' }}
onClick={() => setPayType(0)} onClick={() => setPayType(0)}
> >
<View className='w-8 h-8 rounded-full bg-amber-50 flex items-center justify-center mr-3'> <View className='w-8 h-8 rounded-full bg-blue-50 flex items-center justify-center mr-3'>
<Text className='text-sm'></Text> <Text className='text-sm'></Text>
</View> </View>
<View className='flex-1'> <View className='flex-1'>
<Text className='text-sm text-gray-800 block'></Text> <Text className='text-sm text-gray-800 block'></Text>
<Text className='text-xs text-gray-400 block'> <Text className='text-xs text-gray-400 block'></Text>
{loadingBalance ? '加载中...' : `可用: ¥${parseFloat(userBalance).toFixed(2)}`}
</Text>
</View> </View>
<View <View
className='w-5 h-5 rounded-full border-2 flex items-center justify-center' className='w-5 h-5 rounded-full border-2 flex items-center justify-center'
@@ -564,15 +513,6 @@ const CheckoutPage: React.FC = () => {
)} )}
</View> </View>
</View> </View>
{/* 余额不足提示 */}
{payType === 0 && parseFloat(userBalance) < parseFloat(totalPrice) && (
<View className='mt-2 px-2'>
<Text className='text-xs text-red-500'>
¥{(parseFloat(totalPrice) - parseFloat(userBalance)).toFixed(2)}
</Text>
</View>
)}
</View> </View>
{/* 凑单推荐 */} {/* 凑单推荐 */}

View File

@@ -36,7 +36,7 @@ const helpData: HelpCategory[] = [
title: '支付与退款', title: '支付与退款',
icon: '💰', icon: '💰',
questions: [ questions: [
{ id: 201, title: '支持哪些支付方式?', content: '我们支持微信支付、支付宝支付(如有)、余额支付、积分抵扣等多种支付方式。' }, { id: 201, title: '支持哪些支付方式?', content: '我们支持微信支付、支付宝支付(如有)、货到付款、积分抵扣等多种支付方式。' },
{ id: 202, title: '如何申请退款?', content: '在订单详情页点击"申请退款"按钮,填写退款原因和说明,提交后等待商家审核。' }, { id: 202, title: '如何申请退款?', content: '在订单详情页点击"申请退款"按钮,填写退款原因和说明,提交后等待商家审核。' },
{ id: 203, title: '退款多久到账?', content: '退款审核通过后原路退回您的支付账户。微信支付一般1-3个工作日到账余额支付即时到账。' }, { id: 203, title: '退款多久到账?', content: '退款审核通过后原路退回您的支付账户。微信支付一般1-3个工作日到账余额支付即时到账。' },
] ]