10 changed files with 560 additions and 126 deletions
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
.goods_info_card_component { |
||||
display: flex; |
||||
align-items: flex-start; |
||||
|
||||
// 商品图片 |
||||
.goods_image { |
||||
width: 208px; |
||||
height: 208px; |
||||
border-radius: 8px; |
||||
flex-shrink: 0; |
||||
} |
||||
|
||||
// 商品信息 |
||||
.goods_info { |
||||
flex: 1; |
||||
margin-left: 30px; |
||||
display: flex; |
||||
flex-direction: column; |
||||
padding: 10px 0; |
||||
|
||||
.goods_name { |
||||
font-size: 30px; |
||||
color: #000000; |
||||
font-weight: 600; |
||||
line-height: 1.4; |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
// 价格行 |
||||
.price_row { |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
|
||||
// 有间距的情况(用于订单详情页) |
||||
// &.with_separator { |
||||
margin-top: 56px; // 实现 padding-top: 66px 的效果(66-10=56) |
||||
// } |
||||
|
||||
.price_text { |
||||
font-size: 30px; |
||||
font-weight: 500; |
||||
|
||||
.price_label { |
||||
color: #000000; |
||||
font-weight: 400; |
||||
} |
||||
} |
||||
|
||||
// 右侧按钮区域 |
||||
.right_button_area { |
||||
margin-left: 20px; |
||||
flex-shrink: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/** |
||||
* 商品信息卡片组件 |
||||
* 用于商品消费、订单详情、退款结果等页面 |
||||
*/ |
||||
import { View, Text } from '@tarojs/components' |
||||
import { Image } from '@taroify/core' |
||||
import { ReactNode } from 'react' |
||||
import './index.scss' |
||||
|
||||
export interface GoodsInfoCardProps { |
||||
// 基础信息
|
||||
image: string // 商品图片
|
||||
name: string // 商品名称
|
||||
|
||||
// 金额显示
|
||||
priceLabel?: string // 金额标签(如 "退款:")
|
||||
price: number // 金额
|
||||
priceColor?: string // 金额颜色(默认 #FF3A24)
|
||||
|
||||
// 右侧操作按钮(可选)
|
||||
rightButton?: ReactNode // 自定义右侧按钮
|
||||
|
||||
// 样式定制
|
||||
containerClassName?: string // 容器额外类名
|
||||
showPriceSeparator?: boolean // 是否显示价格和名称之间的间距(默认 true)
|
||||
} |
||||
|
||||
const GoodsInfoCard: React.FC<GoodsInfoCardProps> = ({ |
||||
image, |
||||
name, |
||||
priceLabel, |
||||
price, |
||||
priceColor = '#FF3A24', |
||||
rightButton, |
||||
containerClassName = '', |
||||
showPriceSeparator = true |
||||
}) => { |
||||
return ( |
||||
<View className={`goods_info_card_component ${containerClassName}`}> |
||||
{/* 商品图片 */} |
||||
<Image |
||||
className="goods_image" |
||||
src={image} |
||||
mode="aspectFill" |
||||
width={208} |
||||
height={208} |
||||
/> |
||||
|
||||
{/* 商品信息 */} |
||||
<View className="goods_info"> |
||||
<Text className="goods_name">{name}</Text> |
||||
|
||||
{/* 价格/退款金额行 */} |
||||
<View className={`price_row ${showPriceSeparator ? 'with_separator' : ''}`}> |
||||
<Text className="price_text" style={{ color: priceColor }}> |
||||
{priceLabel && <Text className="price_label">{priceLabel} </Text>} |
||||
¥ {price.toFixed(2)} |
||||
</Text> |
||||
|
||||
{/* 右侧按钮区域 */} |
||||
{rightButton && ( |
||||
<View className="right_button_area"> |
||||
{rightButton} |
||||
</View> |
||||
)} |
||||
</View> |
||||
</View> |
||||
</View> |
||||
) |
||||
} |
||||
|
||||
export default GoodsInfoCard |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
export default { |
||||
navigationBarTitleText: '商品消费', |
||||
navigationBarBackgroundColor: '#FFFFFF', |
||||
navigationBarTextStyle: 'black', |
||||
} |
||||
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
.refund_result_page { |
||||
min-height: 100vh; |
||||
background-color: #F2F3F5; |
||||
padding: 30px; |
||||
|
||||
// 退款结果状态卡片 |
||||
.result_status_card { |
||||
background-color: #FFFFFF; |
||||
border-radius: 12px; |
||||
padding: 50px 30px; |
||||
margin-bottom: 30px; |
||||
text-align: center; |
||||
|
||||
.status_title { |
||||
display: block; |
||||
font-size: 40px; |
||||
font-weight: 600; |
||||
margin-bottom: 30px; |
||||
|
||||
&.success { |
||||
color: #000000; |
||||
} |
||||
|
||||
&.failed { |
||||
color: #EE0A24; |
||||
} |
||||
} |
||||
|
||||
// 成功:退回账户信息 |
||||
.refund_account { |
||||
display: block; |
||||
font-size: 28px; |
||||
color: #333333; |
||||
line-height: 1.5; |
||||
} |
||||
|
||||
// 失败:原因行 |
||||
.fail_reason_row { |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
padding: 0 20px; |
||||
|
||||
.reason_label { |
||||
font-size: 28px; |
||||
color: #333333; |
||||
} |
||||
|
||||
.reason_value { |
||||
font-size: 28px; |
||||
color: #333333; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 商品信息卡片 |
||||
.goods_info_card { |
||||
background-color: #FFFFFF; |
||||
border-radius: 12px; |
||||
padding: 30px; |
||||
margin-bottom: 30px; |
||||
} |
||||
|
||||
// 退款详细信息卡片 |
||||
.refund_detail_card { |
||||
background-color: #FFFFFF; |
||||
border-radius: 12px; |
||||
padding: 30px; |
||||
|
||||
.info_list { |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 20px; |
||||
|
||||
.info_row { |
||||
display: flex; |
||||
align-items: flex-start; |
||||
|
||||
.info_label { |
||||
width: 180px; |
||||
font-size: 28px; |
||||
color: #333333; |
||||
flex-shrink: 0; |
||||
} |
||||
|
||||
.info_value { |
||||
flex: 1; |
||||
margin-left: 30px; |
||||
font-size: 28px; |
||||
color: #595959; |
||||
text-align: left; |
||||
word-break: break-all; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 虚线分隔 |
||||
.divider { |
||||
height: 1PX; |
||||
border-bottom: 1PX dashed #D3D8DE; |
||||
margin: 30px 0; |
||||
} |
||||
|
||||
// 联系商家(仅失败时显示) |
||||
.merchant_contact { |
||||
.contact_text { |
||||
font-size: 28px; |
||||
color: #333333; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
/** |
||||
* 商品订单退款结果页 |
||||
*/ |
||||
import { View, Text } from '@tarojs/components' |
||||
import { useState } from 'react' |
||||
import Taro, { useLoad } from '@tarojs/taro' |
||||
import GoodsInfoCard from '@/components/GoodsInfoCard' |
||||
import './index.scss' |
||||
|
||||
// 退款结果类型
|
||||
type RefundResultType = 'success' | 'failed' |
||||
|
||||
// 商品信息接口
|
||||
interface GoodsInfo { |
||||
id: string |
||||
image: string |
||||
name: string |
||||
refundAmount: number |
||||
} |
||||
|
||||
// 退款结果信息接口
|
||||
interface RefundResultInfo { |
||||
resultType: RefundResultType // 退款结果类型
|
||||
goods: GoodsInfo // 商品信息
|
||||
|
||||
// 成功时的字段
|
||||
refundAccount?: string // 退回账户(微信/支付宝/银行卡)
|
||||
|
||||
// 失败时的字段
|
||||
failReason?: string // 失败原因
|
||||
|
||||
// 通用字段
|
||||
refundReason: string // 退款原因
|
||||
applyAmount: string // 申请金额
|
||||
applyTime: string // 申请时间
|
||||
|
||||
// 成功时额外字段
|
||||
refundCompleteTime?: string // 退款完结时间
|
||||
refundNo?: string // 退款编号
|
||||
|
||||
// 门店信息
|
||||
storeName: string // 消费门店
|
||||
address: string // 地址
|
||||
merchantPhone?: string // 商家电话(失败时显示)
|
||||
} |
||||
|
||||
const GoodsRefundResult = () => { |
||||
const [pageType, setPageType] = useState<RefundResultType>('success') |
||||
|
||||
// 模拟退款结果数据
|
||||
const [refundInfo] = useState<RefundResultInfo>({ |
||||
resultType: 'success', |
||||
goods: { |
||||
id: '1', |
||||
image: 'https://img01.yzcdn.cn/vant/cat.jpeg', |
||||
name: '美汁源Minute Maid果粒橙 橙汁饮料 1.25l/瓶', |
||||
refundAmount: 12.50 |
||||
}, |
||||
refundAccount: '微信/支付宝/银行卡(中国银行6666)', |
||||
refundReason: '计算错误', |
||||
applyAmount: '12.50元', |
||||
applyTime: '2025-01-01 12:00:00', |
||||
refundCompleteTime: '2025-01-01 12:06:00', |
||||
refundNo: 'a202501011206060000', |
||||
storeName: 'XXXXXXXXX店', |
||||
address: 'XXX市XXXXXXX区XXXXXXXXXX街道XXX大厦101', |
||||
merchantPhone: '16688889999', |
||||
failReason: '已成功取货' |
||||
}) |
||||
|
||||
useLoad(() => { |
||||
console.log('退款结果页面加载') |
||||
|
||||
// 从 URL 获取页面类型
|
||||
const router = Taro.getCurrentInstance().router |
||||
if (router?.params) { |
||||
const { type } = router.params |
||||
if (type === 'success' || type === 'failed') { |
||||
setPageType(type as RefundResultType) |
||||
} |
||||
} |
||||
}) |
||||
|
||||
// 联系商家
|
||||
const handleCallMerchant = () => { |
||||
if (refundInfo.merchantPhone) { |
||||
Taro.makePhoneCall({ |
||||
phoneNumber: refundInfo.merchantPhone |
||||
}) |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<View className="refund_result_page"> |
||||
{/* 退款结果状态卡片 */} |
||||
<View className="result_status_card"> |
||||
<Text className={`status_title ${pageType === 'success' ? 'success' : 'failed'}`}> |
||||
{pageType === 'success' ? '退款成功' : '退款失败'} |
||||
</Text> |
||||
|
||||
{pageType === 'success' ? ( |
||||
// 成功:显示退回账户信息
|
||||
<Text className="refund_account"> |
||||
退回{refundInfo.refundAccount} ¥ {refundInfo.goods.refundAmount.toFixed(2)} |
||||
</Text> |
||||
) : ( |
||||
// 失败:显示失败原因
|
||||
<View className="fail_reason_row"> |
||||
<Text className="reason_label">原因</Text> |
||||
<Text className="reason_value">{refundInfo.failReason}</Text> |
||||
</View> |
||||
)} |
||||
</View> |
||||
|
||||
{/* 商品信息卡片 */} |
||||
<View className="goods_info_card"> |
||||
<GoodsInfoCard |
||||
image={refundInfo.goods.image} |
||||
name={refundInfo.goods.name} |
||||
priceLabel="退款:" |
||||
price={refundInfo.goods.refundAmount} |
||||
priceColor="#000000" |
||||
showPriceSeparator={false} |
||||
/> |
||||
</View> |
||||
|
||||
{/* 退款详细信息卡片 */} |
||||
<View className="refund_detail_card"> |
||||
<View className="info_list"> |
||||
<View className="info_row"> |
||||
<Text className="info_label">退款原因</Text> |
||||
<Text className="info_value">{refundInfo.refundReason}</Text> |
||||
</View> |
||||
<View className="info_row"> |
||||
<Text className="info_label">申请金额</Text> |
||||
<Text className="info_value">{refundInfo.applyAmount}</Text> |
||||
</View> |
||||
<View className="info_row"> |
||||
<Text className="info_label">申请时间</Text> |
||||
<Text className="info_value">{refundInfo.applyTime}</Text> |
||||
</View> |
||||
|
||||
{/* 成功时显示退款完结和退款编号 */} |
||||
{pageType === 'success' && ( |
||||
<> |
||||
<View className="info_row"> |
||||
<Text className="info_label">退款完结</Text> |
||||
<Text className="info_value">{refundInfo.refundCompleteTime}</Text> |
||||
</View> |
||||
<View className="info_row"> |
||||
<Text className="info_label">退款编号</Text> |
||||
<Text className="info_value">{refundInfo.refundNo}</Text> |
||||
</View> |
||||
</> |
||||
)} |
||||
|
||||
<View className="info_row"> |
||||
<Text className="info_label">消费门店</Text> |
||||
<Text className="info_value">{refundInfo.storeName}</Text> |
||||
</View> |
||||
<View className="info_row"> |
||||
<Text className="info_label">地址</Text> |
||||
<Text className="info_value">{refundInfo.address}</Text> |
||||
</View> |
||||
</View> |
||||
|
||||
{/* 失败时显示联系商家 */} |
||||
{pageType === 'failed' && refundInfo.merchantPhone && ( |
||||
<> |
||||
<View className="divider" /> |
||||
<View className="merchant_contact" onClick={handleCallMerchant}> |
||||
<Text className="contact_text">联系商家:{refundInfo.merchantPhone}</Text> |
||||
</View> |
||||
</> |
||||
)} |
||||
</View> |
||||
</View> |
||||
) |
||||
} |
||||
|
||||
export default GoodsRefundResult |
||||
Loading…
Reference in new issue