11 changed files with 1456 additions and 28 deletions
@ -0,0 +1,292 @@ |
|||||||
|
/** |
||||||
|
* 卡券使用页面样式 |
||||||
|
*/ |
||||||
|
.coupon_use_page { |
||||||
|
min-height: 100vh; |
||||||
|
background-color: #121212; |
||||||
|
padding-bottom: 180px; |
||||||
|
|
||||||
|
// 卡券信息区域 |
||||||
|
.coupon_info_section { |
||||||
|
padding: 30px; |
||||||
|
background-color: #121212; |
||||||
|
|
||||||
|
.coupon_header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: flex-start; |
||||||
|
|
||||||
|
.coupon_title_area { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
gap: 12px; |
||||||
|
padding-right: 30px; |
||||||
|
|
||||||
|
.coupon_title { |
||||||
|
font-size: 33px; |
||||||
|
color: #FEFEFE; |
||||||
|
font-weight: 500; |
||||||
|
line-height: 1.4; |
||||||
|
} |
||||||
|
|
||||||
|
.coupon_valid { |
||||||
|
font-size: 25px; |
||||||
|
color: #A8A8A8; |
||||||
|
line-height: 1.4; |
||||||
|
} |
||||||
|
|
||||||
|
.coupon_method { |
||||||
|
font-size: 25px; |
||||||
|
color: #A8A8A8; |
||||||
|
line-height: 1.4; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.coupon_duration_area { |
||||||
|
flex-shrink: 0; |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
|
||||||
|
.duration_value { |
||||||
|
font-size: 60px; |
||||||
|
color: #A8A8A8; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.duration_unit { |
||||||
|
font-size: 25px; |
||||||
|
color: #A8A8A8; |
||||||
|
margin-left: 4px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 选择门店区域 |
||||||
|
.store_select_section { |
||||||
|
padding: 30px; |
||||||
|
padding-top: 0; |
||||||
|
|
||||||
|
.section_title_row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 15px; |
||||||
|
|
||||||
|
.section_title { |
||||||
|
font-size: 31px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
|
||||||
|
.partial_tip { |
||||||
|
font-size: 25px; |
||||||
|
color: #A8A8A8; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.selected_store { |
||||||
|
font-size: 27px; |
||||||
|
color: #A8A8A8; |
||||||
|
margin-bottom: 25px; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
// 搜索栏 |
||||||
|
.search_row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
background-color: #21212A; |
||||||
|
border: 1PX solid #444444; |
||||||
|
border-radius: 8px; |
||||||
|
height: 80px; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
.city_dropdown { |
||||||
|
flex-shrink: 0; |
||||||
|
width: 160px; |
||||||
|
height: 100%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
border-right: 1PX solid #444444; |
||||||
|
padding: 0 15px; |
||||||
|
gap: 8px; |
||||||
|
|
||||||
|
.city_text { |
||||||
|
font-size: 27px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.city_arrow { |
||||||
|
font-size: 20px; |
||||||
|
color: #FFFFFF; |
||||||
|
transform: rotate(90deg); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.search_input { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 0 20px; |
||||||
|
height: 100%; |
||||||
|
|
||||||
|
.search_field { |
||||||
|
flex: 1; |
||||||
|
font-size: 27px; |
||||||
|
color: #FFFFFF; |
||||||
|
background-color: #21212A; |
||||||
|
} |
||||||
|
|
||||||
|
.search_placeholder { |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
|
||||||
|
.search_icon { |
||||||
|
flex-shrink: 0; |
||||||
|
font-size: 36px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 城市选择弹窗 |
||||||
|
.city_picker { |
||||||
|
background-color: #21212A; |
||||||
|
padding: 30px; |
||||||
|
padding-bottom: calc(30px + env(safe-area-inset-bottom)); |
||||||
|
|
||||||
|
.picker_header { |
||||||
|
text-align: center; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
.picker_title { |
||||||
|
font-size: 33px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.picker_options { |
||||||
|
.picker_option { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 30px 20px; |
||||||
|
border-bottom: 1PX solid #2A2A2A; |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
&.selected { |
||||||
|
.option_text { |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.option_text { |
||||||
|
font-size: 29px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.check_icon { |
||||||
|
font-size: 29px; |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 门店列表 |
||||||
|
.store_list { |
||||||
|
padding: 0 30px; |
||||||
|
|
||||||
|
.store_card { |
||||||
|
background-color: #21212A; |
||||||
|
border-radius: 12px; |
||||||
|
padding: 30px; |
||||||
|
margin-bottom: 20px; |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: flex-start; |
||||||
|
position: relative; |
||||||
|
overflow: hidden; |
||||||
|
transition: all 0.2s ease; |
||||||
|
border: 1px solid #21212A; |
||||||
|
// 选中状态 - 边框 |
||||||
|
&.selected { |
||||||
|
border: 1px solid #03C175; |
||||||
|
} |
||||||
|
|
||||||
|
.store_info { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
gap: 12px; |
||||||
|
padding-right: 20px; |
||||||
|
|
||||||
|
.store_name { |
||||||
|
font-size: 30px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: 500; |
||||||
|
line-height: 1.4; |
||||||
|
} |
||||||
|
|
||||||
|
.store_address { |
||||||
|
font-size: 25px; |
||||||
|
color: #E5E5E5; |
||||||
|
line-height: 1.5; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.store_distance { |
||||||
|
flex-shrink: 0; |
||||||
|
|
||||||
|
.distance_text { |
||||||
|
font-size: 25px; |
||||||
|
color: #E5E5E5; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 到底提示 |
||||||
|
.end_tip { |
||||||
|
display: block; |
||||||
|
text-align: center; |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
margin: 40px 0; |
||||||
|
} |
||||||
|
|
||||||
|
// 页脚 |
||||||
|
.footer { |
||||||
|
position: fixed; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
background-color: #121212; |
||||||
|
padding: 20px 30px; |
||||||
|
padding-bottom: calc(20px + env(safe-area-inset-bottom)); |
||||||
|
border-top: 1PX solid #2A2A2A; |
||||||
|
|
||||||
|
.use_btn { |
||||||
|
width: 100%; |
||||||
|
height: 88px; |
||||||
|
background-color: #03C175; |
||||||
|
border-radius: 44px; |
||||||
|
border: none; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
font-size: 31px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,236 @@ |
|||||||
|
/** |
||||||
|
* 卡券使用页面 |
||||||
|
*/ |
||||||
|
import { View, Text, Input } from '@tarojs/components' |
||||||
|
import Taro, { useLoad, useRouter } from '@tarojs/taro' |
||||||
|
import { useState } from 'react' |
||||||
|
import { Popup, Button } from '@taroify/core' |
||||||
|
import { Arrow, Search as SearchIcon } from '@taroify/icons' |
||||||
|
import './index.scss' |
||||||
|
|
||||||
|
// 门店数据接口
|
||||||
|
interface Store { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
address: string |
||||||
|
distance: string |
||||||
|
} |
||||||
|
|
||||||
|
// 城市选项
|
||||||
|
const cityOptions = [ |
||||||
|
{ title: '选城市', value: 'all' }, |
||||||
|
{ title: '北京', value: 'beijing' }, |
||||||
|
{ title: '上海', value: 'shanghai' }, |
||||||
|
{ title: '广州', value: 'guangzhou' }, |
||||||
|
{ title: '深圳', value: 'shenzhen' }, |
||||||
|
] |
||||||
|
|
||||||
|
const CouponUse = () => { |
||||||
|
const router = useRouter() |
||||||
|
const { couponId } = router.params |
||||||
|
|
||||||
|
// 卡券信息(从路由参数或上一页面传递,实际应根据couponId获取)
|
||||||
|
const [couponInfo] = useState({ |
||||||
|
title: '豪华自助台球厅20分钟通用券(体验券)', |
||||||
|
duration: '20', |
||||||
|
validPeriod: '2025.10.01 - 2025.10.07(有效7天)', |
||||||
|
useMethod: '自动抵扣,单次使用', |
||||||
|
partialUsable: true, // 部分门店不可用
|
||||||
|
}) |
||||||
|
|
||||||
|
// 城市选择
|
||||||
|
const [selectedCity, setSelectedCity] = useState('all') |
||||||
|
const [showCityPicker, setShowCityPicker] = useState(false) |
||||||
|
|
||||||
|
// 搜索关键词
|
||||||
|
const [searchValue, setSearchValue] = useState('') |
||||||
|
|
||||||
|
// 已选门店
|
||||||
|
const [selectedStoreId, setSelectedStoreId] = useState<number | null>(1) |
||||||
|
|
||||||
|
// 门店列表(模拟数据)
|
||||||
|
const [storeList] = useState<Store[]>([ |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '北京黑八大师联盟球厅店', |
||||||
|
address: '北京市XXX区XXX街道XXXXXXXXXXXXXXXXXXXXXXX路19号606', |
||||||
|
distance: '0.05km' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 2, |
||||||
|
name: '北京晶彩桌球世界店', |
||||||
|
address: '北京市XXX区XXX街道XXX路19号606', |
||||||
|
distance: '0.1km' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 3, |
||||||
|
name: '北京球坛风云店', |
||||||
|
address: '北京市XXX区XXXXXXXXXXX街道XXX路19号606', |
||||||
|
distance: '0.2km' |
||||||
|
}, |
||||||
|
]) |
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
console.log('卡券使用页面加载') |
||||||
|
Taro.setNavigationBarTitle({ title: '' }) |
||||||
|
}) |
||||||
|
|
||||||
|
// 获取已选门店名称
|
||||||
|
const getSelectedStoreName = () => { |
||||||
|
const store = storeList.find(s => s.id === selectedStoreId) |
||||||
|
return store ? store.name : '' |
||||||
|
} |
||||||
|
|
||||||
|
// 选择门店
|
||||||
|
const handleSelectStore = (storeId: number) => { |
||||||
|
setSelectedStoreId(storeId) |
||||||
|
} |
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = () => { |
||||||
|
console.log('搜索', searchValue) |
||||||
|
Taro.showToast({ |
||||||
|
title: `搜索: ${searchValue}`, |
||||||
|
icon: 'none' |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 获取当前城市名称
|
||||||
|
const getCityName = () => { |
||||||
|
const city = cityOptions.find(c => c.value === selectedCity) |
||||||
|
return city ? city.title : '选城市' |
||||||
|
} |
||||||
|
|
||||||
|
// 选择城市
|
||||||
|
const handleSelectCity = (value: string) => { |
||||||
|
setSelectedCity(value) |
||||||
|
setShowCityPicker(false) |
||||||
|
} |
||||||
|
|
||||||
|
// 去使用
|
||||||
|
const handleUse = () => { |
||||||
|
if (!selectedStoreId) { |
||||||
|
Taro.showToast({ |
||||||
|
title: '请选择门店', |
||||||
|
icon: 'none' |
||||||
|
}) |
||||||
|
return |
||||||
|
} |
||||||
|
console.log('使用卡券', selectedStoreId) |
||||||
|
Taro.showToast({ |
||||||
|
title: '卡券使用成功', |
||||||
|
icon: 'success' |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="coupon_use_page"> |
||||||
|
{/* 卡券信息区域 */} |
||||||
|
<View className="coupon_info_section"> |
||||||
|
<View className="coupon_header"> |
||||||
|
<View className="coupon_title_area"> |
||||||
|
<Text className="coupon_title">{couponInfo.title}</Text> |
||||||
|
<Text className="coupon_valid">有效期限:{couponInfo.validPeriod}</Text> |
||||||
|
<Text className="coupon_method">使用方法:{couponInfo.useMethod}</Text> |
||||||
|
</View> |
||||||
|
<View className="coupon_duration_area"> |
||||||
|
<Text className="duration_value">{couponInfo.duration}</Text> |
||||||
|
<Text className="duration_unit">分钟</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
<div style={{height: '1rpx', width:'100%', backgroundColor: '#45454C', margin: '0 24rpx'}}></div> |
||||||
|
|
||||||
|
{/* 选择门店区域 */} |
||||||
|
<View className="store_select_section"> |
||||||
|
<View className="section_title_row"> |
||||||
|
<Text className="section_title">选择门店</Text> |
||||||
|
{couponInfo.partialUsable && ( |
||||||
|
<Text className="partial_tip">(部分门店不可用)</Text> |
||||||
|
)} |
||||||
|
</View> |
||||||
|
<Text className="selected_store">已选门店:{getSelectedStoreName()}</Text> |
||||||
|
|
||||||
|
{/* 搜索栏 */} |
||||||
|
<View className="search_row"> |
||||||
|
<View className="city_dropdown" onClick={() => setShowCityPicker(true)}> |
||||||
|
<Text className="city_text">{getCityName()}</Text> |
||||||
|
<Arrow className="city_arrow" /> |
||||||
|
</View> |
||||||
|
<View className="search_input"> |
||||||
|
<Input |
||||||
|
className="search_field" |
||||||
|
value={searchValue} |
||||||
|
placeholder="搜索门店名称/地址" |
||||||
|
placeholderClass="search_placeholder" |
||||||
|
onInput={(e) => setSearchValue(e.detail.value)} |
||||||
|
onConfirm={handleSearch} |
||||||
|
/> |
||||||
|
<SearchIcon className="search_icon" onClick={handleSearch} /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 城市选择弹窗 */} |
||||||
|
<Popup |
||||||
|
open={showCityPicker} |
||||||
|
placement="bottom" |
||||||
|
rounded |
||||||
|
onClose={() => setShowCityPicker(false)} |
||||||
|
> |
||||||
|
<View className="city_picker"> |
||||||
|
<View className="picker_header"> |
||||||
|
<Text className="picker_title">选择城市</Text> |
||||||
|
</View> |
||||||
|
<View className="picker_options"> |
||||||
|
{cityOptions.map((city) => ( |
||||||
|
<View |
||||||
|
key={city.value} |
||||||
|
className={`picker_option ${selectedCity === city.value ? 'selected' : ''}`} |
||||||
|
onClick={() => handleSelectCity(city.value)} |
||||||
|
> |
||||||
|
<Text className="option_text">{city.title}</Text> |
||||||
|
{selectedCity === city.value && <Text className="check_icon">✓</Text>} |
||||||
|
</View> |
||||||
|
))} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</Popup> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 门店列表 */} |
||||||
|
<View className="store_list"> |
||||||
|
{storeList.map((store) => ( |
||||||
|
<View |
||||||
|
key={store.id} |
||||||
|
className={`store_card ${selectedStoreId === store.id ? 'selected' : ''}`} |
||||||
|
onClick={() => handleSelectStore(store.id)} |
||||||
|
> |
||||||
|
<View className="store_info"> |
||||||
|
<Text className="store_name">{store.name}</Text> |
||||||
|
<Text className="store_address">{store.address}</Text> |
||||||
|
</View> |
||||||
|
<View className="store_distance"> |
||||||
|
<Text className="distance_text">距离{store.distance}</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
))} |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 到底提示 */} |
||||||
|
<Text className="end_tip">到底了~</Text> |
||||||
|
|
||||||
|
{/* 页脚按钮 */} |
||||||
|
<View className="footer"> |
||||||
|
<Button |
||||||
|
className="use_btn" |
||||||
|
onClick={handleUse} |
||||||
|
> |
||||||
|
去使用 |
||||||
|
</Button> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CouponUse |
||||||
@ -0,0 +1,295 @@ |
|||||||
|
/** |
||||||
|
* 预定页面样式 |
||||||
|
*/ |
||||||
|
.reservation_page { |
||||||
|
min-height: 100vh; |
||||||
|
background-color: #121212; |
||||||
|
padding-bottom: 130px; // 为底部固定区域留空间 |
||||||
|
|
||||||
|
// 内容区域 |
||||||
|
.content_area { |
||||||
|
padding: 30px 30px 0; |
||||||
|
|
||||||
|
// 台球桌信息卡片 |
||||||
|
.table_card { |
||||||
|
background-image: url('../../pageScan/startTable/images/startBiliardCardBg.png'); |
||||||
|
background-size: cover; |
||||||
|
background-position: center; |
||||||
|
border-radius: 12px; |
||||||
|
padding: 24px; |
||||||
|
margin-bottom: 30px; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
// 顶部:店名和电话 |
||||||
|
.card_header { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 20px; |
||||||
|
|
||||||
|
.store_name { |
||||||
|
font-size: 25px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.phone_box { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 8px; |
||||||
|
|
||||||
|
.phone_icon { |
||||||
|
width: 29px; |
||||||
|
height: 29px; |
||||||
|
} |
||||||
|
|
||||||
|
.phone_text { |
||||||
|
font-size: 25px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 台球桌标题 |
||||||
|
.table_title { |
||||||
|
font-weight: bold; |
||||||
|
font-size: 42px; |
||||||
|
color: #FFFFFF; |
||||||
|
line-height: 1.4; |
||||||
|
margin: 24px 0 26px; |
||||||
|
} |
||||||
|
|
||||||
|
// 价格信息 |
||||||
|
.price_info { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 10px; |
||||||
|
margin-bottom: 24px; |
||||||
|
|
||||||
|
.price_item { |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
gap: 2px; |
||||||
|
|
||||||
|
.price_label { |
||||||
|
font-size: 25px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.price_value { |
||||||
|
font-size: 22px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: bold; |
||||||
|
// 文字渐变色 |
||||||
|
background: linear-gradient(0deg, #F6AE54 0%, #FBE49E 50%, #F6AE54 100%); |
||||||
|
-webkit-background-clip: text; |
||||||
|
-webkit-text-fill-color: transparent; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.vip_price { |
||||||
|
background: linear-gradient(90deg, #333333 0%, #000000 100%); |
||||||
|
border-radius: 8px; |
||||||
|
padding: 7px 9px; |
||||||
|
|
||||||
|
.vip_text { |
||||||
|
font-size: 22px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 价格时段 |
||||||
|
.time_period { |
||||||
|
font-size: 25px; |
||||||
|
color: #fFF; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 费用信息卡片 |
||||||
|
.fee_card { |
||||||
|
background-color: #21212A; |
||||||
|
border-radius: 13px; |
||||||
|
padding: 30px; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
// 费用行 |
||||||
|
.fee_row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
.fee_label { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.fee_value { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 分割线 |
||||||
|
.divider { |
||||||
|
height: 1PX; |
||||||
|
background-color: #3A3D42; |
||||||
|
margin: 30px 0; |
||||||
|
} |
||||||
|
|
||||||
|
// 收费标准行 |
||||||
|
.fee_standard_row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
.fee_label { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.fee_right { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 10px; |
||||||
|
|
||||||
|
.fee_value { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.arrow_icon { |
||||||
|
font-size: 28px; |
||||||
|
color: #E6E6E6; |
||||||
|
transition: transform 0.3s ease; |
||||||
|
transform: rotate(90deg); // 默认向下 |
||||||
|
|
||||||
|
&.expanded { |
||||||
|
transform: rotate(-90deg); // 展开时向上 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 收费标准详情 |
||||||
|
.fee_detail { |
||||||
|
margin-top: 20px; |
||||||
|
padding: 20px; |
||||||
|
background-color: #2A2A35; |
||||||
|
border-radius: 8px; |
||||||
|
|
||||||
|
.detail_text { |
||||||
|
display: block; |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
line-height: 1.6; |
||||||
|
margin-bottom: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.detail_item { |
||||||
|
display: block; |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
line-height: 1.8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 支付方式单元格 |
||||||
|
.payment_cell { |
||||||
|
height: 100px; |
||||||
|
background-color: #21212A; |
||||||
|
margin-bottom: 30px; |
||||||
|
border-radius: 13px; |
||||||
|
padding: 0 30px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
.payment_label { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.payment_right { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 8px; |
||||||
|
|
||||||
|
.payment_value { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.payment_arrow { |
||||||
|
font-size: 28px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 温馨提示 |
||||||
|
.tips_section { |
||||||
|
padding: 0 10px; |
||||||
|
|
||||||
|
.tips_text { |
||||||
|
display: block; |
||||||
|
font-size: 25px; |
||||||
|
color: #666666; |
||||||
|
line-height: 1.8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 底部固定区域 |
||||||
|
.footer_bar { |
||||||
|
position: fixed; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
height: 130px; |
||||||
|
background-color: #1A1A1A; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 0 30px; |
||||||
|
box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.3); |
||||||
|
|
||||||
|
// 支付信息 |
||||||
|
.payment_info { |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
gap: 8px; |
||||||
|
|
||||||
|
.payment_label { |
||||||
|
font-size: 28px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.payment_symbol { |
||||||
|
font-size: 28px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.payment_amount { |
||||||
|
font-size: 45px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 立即预定按钮 |
||||||
|
.confirm_btn { |
||||||
|
background-color: #01CA68; |
||||||
|
border-radius: 50px; |
||||||
|
padding: 20px 60px; |
||||||
|
|
||||||
|
.confirm_text { |
||||||
|
font-size: 31px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,158 @@ |
|||||||
|
/** |
||||||
|
* 预定页面 |
||||||
|
*/ |
||||||
|
import { View, Text, Image } from '@tarojs/components' |
||||||
|
import Taro, { useLoad } from '@tarojs/taro' |
||||||
|
import { useState } from 'react' |
||||||
|
import { Arrow } from '@taroify/icons' |
||||||
|
import './index.scss' |
||||||
|
|
||||||
|
// 使用本地图片资源
|
||||||
|
const phoneIcon = require('../../pageScan/startTable/images/phone.png') |
||||||
|
|
||||||
|
const Reservation = () => { |
||||||
|
const [paymentMethod] = useState('微信支付') // 支付方式
|
||||||
|
const [showFeeDetail, setShowFeeDetail] = useState(true) // 是否展示收费标准详情
|
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
console.log('预定页面加载') |
||||||
|
}) |
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const handlePhoneCall = () => { |
||||||
|
Taro.makePhoneCall({ |
||||||
|
phoneNumber: '100-666-XXXX', |
||||||
|
}).catch((err) => { |
||||||
|
console.error('拨打电话失败:', err) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 选择支付方式
|
||||||
|
const handleSelectPayment = () => { |
||||||
|
Taro.showToast({ |
||||||
|
title: '暂时只支持微信支付', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 切换收费标准展开/收起
|
||||||
|
const toggleFeeDetail = () => { |
||||||
|
setShowFeeDetail(!showFeeDetail) |
||||||
|
} |
||||||
|
|
||||||
|
// 立即预定
|
||||||
|
const handleConfirmReservation = () => { |
||||||
|
console.log('立即预定') |
||||||
|
Taro.showToast({ |
||||||
|
title: '功能开发中', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="reservation_page"> |
||||||
|
{/* 内容区域 */} |
||||||
|
<View className="content_area"> |
||||||
|
{/* 台球桌信息卡片 */} |
||||||
|
<View className="table_card"> |
||||||
|
{/* 顶部:店名和电话 */} |
||||||
|
<View className="card_header"> |
||||||
|
<Text className="store_name">北京黑八大师联盟球厅店</Text> |
||||||
|
<View className="phone_box" onClick={handlePhoneCall}> |
||||||
|
<Image className="phone_icon" src={phoneIcon} mode="aspectFit" /> |
||||||
|
<Text className="phone_text">联系店长</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 台球桌标题 */} |
||||||
|
<View className="table_title"> |
||||||
|
<Text>[台球]来力黑金刚03</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 价格信息 */} |
||||||
|
<View className="price_info"> |
||||||
|
<View className="price_item"> |
||||||
|
<Text className="price_value">¥60.00</Text> |
||||||
|
<Text className="price_label">/小时,</Text> |
||||||
|
</View> |
||||||
|
<View className="price_item"> |
||||||
|
<Text className="price_label">押金</Text> |
||||||
|
<Text className="price_value">¥100.00</Text> |
||||||
|
</View> |
||||||
|
<View className="vip_price"> |
||||||
|
<Text className="vip_text">VIP ¥50.00</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 价格时段 */} |
||||||
|
<View className="time_period"> |
||||||
|
<Text>价格时段:00:00-24:00</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 费用信息卡片 */} |
||||||
|
<View className="fee_card"> |
||||||
|
{/* 预定金 */} |
||||||
|
<View className="fee_row"> |
||||||
|
<Text className="fee_label">预定金</Text> |
||||||
|
<Text className="fee_value">30元</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 分割线 */} |
||||||
|
<View className="divider" /> |
||||||
|
|
||||||
|
{/* 收费标准 */} |
||||||
|
<View className="fee_standard_row" onClick={toggleFeeDetail}> |
||||||
|
<Text className="fee_label">收费标准</Text> |
||||||
|
<View className="fee_right"> |
||||||
|
<Text className="fee_value">80元/小时</Text> |
||||||
|
<Arrow className={`arrow_icon ${showFeeDetail ? 'expanded' : ''}`} /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 收费标准详情 */} |
||||||
|
{showFeeDetail && ( |
||||||
|
<View className="fee_detail"> |
||||||
|
<Text className="detail_text">1分钟以内不计费,超过1分钟按6.67元/5分钟计费</Text> |
||||||
|
<Text className="detail_item">• 00:00-11:00 原价90元/小时,折扣价80元/小时</Text> |
||||||
|
<Text className="detail_item">• 11:00-24:00 原价100元/小时,折扣价90元/小时</Text> |
||||||
|
</View> |
||||||
|
)} |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 支付方式 */} |
||||||
|
<View className="payment_cell" onClick={handleSelectPayment}> |
||||||
|
<Text className="payment_label">支付方式</Text> |
||||||
|
<View className="payment_right"> |
||||||
|
<Text className="payment_value">{paymentMethod}</Text> |
||||||
|
<Arrow className="payment_arrow" /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 温馨提示 */} |
||||||
|
<View className="tips_section"> |
||||||
|
<Text className="tips_text">温馨提示:(预定桌台时间:10分钟)</Text> |
||||||
|
<Text className="tips_text">1. 预定桌台成功后,3分钟内取消可退回预定金,3分钟后无法取消;</Text> |
||||||
|
<Text className="tips_text">2. 预定10分钟内开台成功,预定金原路退回;</Text> |
||||||
|
<Text className="tips_text">3. 未在预定时间内开台,则扣除预定金(预定金自动充值至账户余额)。</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 底部固定区域 */} |
||||||
|
<View className="footer_bar"> |
||||||
|
<View className="payment_info"> |
||||||
|
<Text className="payment_label">需支付</Text> |
||||||
|
<Text className="payment_symbol">¥</Text> |
||||||
|
<Text className="payment_amount">30.00</Text> |
||||||
|
</View> |
||||||
|
<View className="confirm_btn" onClick={handleConfirmReservation}> |
||||||
|
<Text className="confirm_text">立即预定</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Reservation |
||||||
@ -0,0 +1,167 @@ |
|||||||
|
/** |
||||||
|
* 历史优惠券页面样式 |
||||||
|
*/ |
||||||
|
.history_coupons_page { |
||||||
|
min-height: 100vh; |
||||||
|
background-color: #F2F3F5; |
||||||
|
|
||||||
|
// Tab 容器 |
||||||
|
.tab_container { |
||||||
|
background-color: #FFFFFF; |
||||||
|
|
||||||
|
:global { |
||||||
|
// Tab 导航容器 |
||||||
|
.taroify-tabs__nav { |
||||||
|
background-color: #FFFFFF !important; |
||||||
|
} |
||||||
|
|
||||||
|
// 未选中 Tab |
||||||
|
.taroify-tabs__tab { |
||||||
|
font-size: 33px !important; |
||||||
|
color: #8B8B8B !important; |
||||||
|
} |
||||||
|
|
||||||
|
// 选中 Tab |
||||||
|
.taroify-tabs__tab--active { |
||||||
|
color: #03C175 !important; |
||||||
|
} |
||||||
|
|
||||||
|
// 选中指示线 |
||||||
|
.taroify-tabs__line { |
||||||
|
background-color: #03C175 !important; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 内容区域 |
||||||
|
.content_area { |
||||||
|
padding: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
// 优惠券列表 |
||||||
|
.coupon_list { |
||||||
|
// 优惠券卡片 |
||||||
|
.coupon_card { |
||||||
|
background-color: #FFFFFF; |
||||||
|
border-radius: 12px; |
||||||
|
padding: 30px; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
// 标题行 |
||||||
|
.card_header { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
.coupon_name { |
||||||
|
flex: 1; |
||||||
|
font-size: 33px; |
||||||
|
color: #1A1A1A; |
||||||
|
font-weight: 500; |
||||||
|
padding-right: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.status_tag { |
||||||
|
flex-shrink: 0; |
||||||
|
padding: 8px 20px; |
||||||
|
border-radius: 25px; |
||||||
|
border: 1px solid; |
||||||
|
|
||||||
|
&.used { |
||||||
|
border-color: #03C175; |
||||||
|
|
||||||
|
.status_text { |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.expired { |
||||||
|
border-color: #8B8B8B; |
||||||
|
|
||||||
|
.status_text { |
||||||
|
color: #8B8B8B; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.status_text { |
||||||
|
font-size: 25px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 分割线 |
||||||
|
.divider { |
||||||
|
height: 1PX; |
||||||
|
border-bottom: 1PX dashed #D3D8DE; |
||||||
|
margin: 30px 0; |
||||||
|
} |
||||||
|
|
||||||
|
// 信息区块 |
||||||
|
.section { |
||||||
|
margin-bottom: 25px; |
||||||
|
|
||||||
|
&:last-of-type { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.section_title { |
||||||
|
font-size: 29px; |
||||||
|
color: #1A1A1A; |
||||||
|
font-weight: 500; |
||||||
|
margin-bottom: 20px; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.info_list { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
gap: 16px; |
||||||
|
|
||||||
|
.info_row { |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
|
||||||
|
.info_label { |
||||||
|
width: 140px; |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 展开/收起按钮 |
||||||
|
.expand_btn { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
padding-top: 20px; |
||||||
|
|
||||||
|
.expand_icon { |
||||||
|
font-size: 28px; |
||||||
|
color: #999999; |
||||||
|
transition: transform 0.3s ease; |
||||||
|
transform: rotate(90deg); // 默认向下 |
||||||
|
|
||||||
|
&.expanded { |
||||||
|
transform: rotate(-90deg); // 展开时向上 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,203 @@ |
|||||||
|
/** |
||||||
|
* 历史优惠券页面 |
||||||
|
*/ |
||||||
|
import { View, Text } from '@tarojs/components' |
||||||
|
import { useState } from 'react' |
||||||
|
import Taro, { useLoad } from '@tarojs/taro' |
||||||
|
import { Tabs } from '@taroify/core' |
||||||
|
import { Arrow } from '@taroify/icons' |
||||||
|
import EmptyData from '@/components/EmptyData' |
||||||
|
import './index.scss' |
||||||
|
|
||||||
|
// 优惠券数据接口
|
||||||
|
interface CouponItem { |
||||||
|
id: string |
||||||
|
name: string // 券名称
|
||||||
|
status: 'used' | 'expired' // 状态:已使用、已过期
|
||||||
|
// 基础信息
|
||||||
|
couponName: string // 卡券名称
|
||||||
|
couponNo: string // 卡券编号
|
||||||
|
couponType: string // 卡券类型
|
||||||
|
deductDuration: string // 抵扣时长
|
||||||
|
validDays: string // 有效期
|
||||||
|
// 使用信息
|
||||||
|
useTime?: string // 使用时间
|
||||||
|
useStore?: string // 使用门店
|
||||||
|
useStatus: string // 使用状态
|
||||||
|
} |
||||||
|
|
||||||
|
const HistoryCoupons = () => { |
||||||
|
const [activeTab, setActiveTab] = useState(0) // 0: 全部, 1: 已使用, 2: 已过期
|
||||||
|
const [expandedIds, setExpandedIds] = useState<string[]>([]) // 展开的卡片ID列表
|
||||||
|
|
||||||
|
// 模拟优惠券数据
|
||||||
|
const [coupons] = useState<CouponItem[]>([ |
||||||
|
{ |
||||||
|
id: '1', |
||||||
|
name: '满40分钟减20分钟(体验券)', |
||||||
|
status: 'expired', |
||||||
|
couponName: '满40分钟减20分钟(体验券)', |
||||||
|
couponNo: '35693280569032705793', |
||||||
|
couponType: '抵时券', |
||||||
|
deductDuration: '20分钟', |
||||||
|
validDays: '7天', |
||||||
|
useTime: '-', |
||||||
|
useStore: '-', |
||||||
|
useStatus: '已过期' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '2', |
||||||
|
name: '自助台球厅3小时59.9元体验券', |
||||||
|
status: 'used', |
||||||
|
couponName: '自助台球厅3小时59.9元体验券', |
||||||
|
couponNo: '90327057933569328056', |
||||||
|
couponType: '抵时券', |
||||||
|
deductDuration: '180分钟', |
||||||
|
validDays: '7天', |
||||||
|
useTime: '2025-01-01 23:00:00', |
||||||
|
useStore: '北京黑八大师联盟球厅店', |
||||||
|
useStatus: '已使用' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '3', |
||||||
|
name: '台球2小时29.9元体验券', |
||||||
|
status: 'used', |
||||||
|
couponName: '台球2小时29.9元体验券', |
||||||
|
couponNo: '90327028056579335693', |
||||||
|
couponType: '抵时券', |
||||||
|
deductDuration: '120分钟', |
||||||
|
validDays: '7天', |
||||||
|
useTime: '2025-01-02 15:30:00', |
||||||
|
useStore: '北京晶彩桌球世界店', |
||||||
|
useStatus: '已使用' |
||||||
|
} |
||||||
|
]) |
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
console.log('历史优惠券页面加载') |
||||||
|
}) |
||||||
|
|
||||||
|
// 切换展开/收起
|
||||||
|
const toggleExpand = (id: string) => { |
||||||
|
setExpandedIds(prev => { |
||||||
|
if (prev.includes(id)) { |
||||||
|
return prev.filter(item => item !== id) |
||||||
|
} |
||||||
|
return [...prev, id] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 判断是否展开
|
||||||
|
const isExpanded = (id: string) => { |
||||||
|
return expandedIds.includes(id) |
||||||
|
} |
||||||
|
|
||||||
|
// 根据 tab 过滤数据
|
||||||
|
const getFilteredCoupons = () => { |
||||||
|
if (activeTab === 0) return coupons // 全部
|
||||||
|
if (activeTab === 1) return coupons.filter(c => c.status === 'used') // 已使用
|
||||||
|
if (activeTab === 2) return coupons.filter(c => c.status === 'expired') // 已过期
|
||||||
|
return coupons |
||||||
|
} |
||||||
|
|
||||||
|
// 渲染优惠券卡片
|
||||||
|
const renderCouponCard = (coupon: CouponItem) => { |
||||||
|
const expanded = isExpanded(coupon.id) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View key={coupon.id} className="coupon_card"> |
||||||
|
{/* 标题行 */} |
||||||
|
<View className="card_header"> |
||||||
|
<Text className="coupon_name">{coupon.name}</Text> |
||||||
|
<View className={`status_tag ${coupon.status}`}> |
||||||
|
<Text className="status_text">{coupon.status === 'used' ? '已使用' : '已过期'}</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 分割线 */} |
||||||
|
<View className="divider" /> |
||||||
|
|
||||||
|
{/* 基础信息 */} |
||||||
|
<View className="section"> |
||||||
|
<Text className="section_title">基础信息</Text> |
||||||
|
<View className="info_list"> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">卡券名称</Text> |
||||||
|
<Text className="info_value">{coupon.couponName}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">卡券编号</Text> |
||||||
|
<Text className="info_value">{coupon.couponNo}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">卡券类型</Text> |
||||||
|
<Text className="info_value">{coupon.couponType}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">抵扣时长</Text> |
||||||
|
<Text className="info_value">{coupon.deductDuration}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">有效期</Text> |
||||||
|
<Text className="info_value">{coupon.validDays}</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 展开后显示使用信息 */} |
||||||
|
{expanded && ( |
||||||
|
<View className="section"> |
||||||
|
<Text className="section_title">使用信息</Text> |
||||||
|
<View className="info_list"> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">使用时间</Text> |
||||||
|
<Text className="info_value">{coupon.useTime}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">使用门店</Text> |
||||||
|
<Text className="info_value">{coupon.useStore}</Text> |
||||||
|
</View> |
||||||
|
<View className="info_row"> |
||||||
|
<Text className="info_label">使用状态</Text> |
||||||
|
<Text className="info_value">{coupon.useStatus}</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
)} |
||||||
|
|
||||||
|
{/* 展开/收起按钮 */} |
||||||
|
<View className="expand_btn" onClick={() => toggleExpand(coupon.id)}> |
||||||
|
<Arrow className={`expand_icon ${expanded ? 'expanded' : ''}`} /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const filteredCoupons = getFilteredCoupons() |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="history_coupons_page"> |
||||||
|
{/* Tab 导航 */} |
||||||
|
<View className="tab_container"> |
||||||
|
<Tabs value={activeTab} onChange={setActiveTab}> |
||||||
|
<Tabs.TabPane title="全部" /> |
||||||
|
<Tabs.TabPane title="已使用" /> |
||||||
|
<Tabs.TabPane title="已过期" /> |
||||||
|
</Tabs> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 内容区域 */} |
||||||
|
<View className="content_area"> |
||||||
|
{filteredCoupons.length === 0 ? ( |
||||||
|
<EmptyData /> |
||||||
|
) : ( |
||||||
|
<View className="coupon_list"> |
||||||
|
{filteredCoupons.map(coupon => renderCouponCard(coupon))} |
||||||
|
</View> |
||||||
|
)} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HistoryCoupons |
||||||
Loading…
Reference in new issue