6 changed files with 770 additions and 0 deletions
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,5 @@ |
|||||||
|
export default definePageConfig({ |
||||||
|
navigationBarTitleText: '团购券开台', |
||||||
|
navigationBarBackgroundColor: '#121212', |
||||||
|
navigationBarTextStyle: 'white', |
||||||
|
}) |
||||||
@ -0,0 +1,449 @@ |
|||||||
|
/** |
||||||
|
* 团购券开台页面样式 |
||||||
|
*/ |
||||||
|
.coupon-start-page { |
||||||
|
min-height: 100vh; |
||||||
|
background-color: #121212; |
||||||
|
padding-bottom: 130px; // 为底部固定区域留空间 |
||||||
|
|
||||||
|
// 内容区域 |
||||||
|
.content-area { |
||||||
|
padding: 30px 30px 0; |
||||||
|
|
||||||
|
// 台球桌信息卡片 |
||||||
|
.table-card { |
||||||
|
background-image: url('../startTable/images/startBiliardCardBg.png'); |
||||||
|
background-size: cover; |
||||||
|
background-position: center; |
||||||
|
border-radius: 12px; |
||||||
|
padding: 24px; |
||||||
|
margin-bottom: 40px; |
||||||
|
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: 20px; |
||||||
|
margin-bottom: 24px; |
||||||
|
|
||||||
|
.price-item { |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
gap: 4px; |
||||||
|
|
||||||
|
.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: #FFFFFF; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 使用说明 |
||||||
|
.instruction-box { |
||||||
|
background-color: #21212A; |
||||||
|
border-radius: 13px; |
||||||
|
padding: 23px; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
.instruction-item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 15px; |
||||||
|
|
||||||
|
&:last-of-type { |
||||||
|
margin-bottom: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.number-circle { |
||||||
|
width: 32px; |
||||||
|
height: 32px; |
||||||
|
// background-color: #FFFFFF; |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
margin-right: 12px; |
||||||
|
flex-shrink: 0; |
||||||
|
|
||||||
|
.number { |
||||||
|
font-size: 20px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.instruction-text { |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.instruction-note { |
||||||
|
display: block; |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
margin-top: 0; |
||||||
|
padding-left: 44px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 券码输入框 |
||||||
|
.code-input-box { |
||||||
|
height: 90px; |
||||||
|
background-color: #2A2A2A; |
||||||
|
border-radius: 8px; |
||||||
|
padding: 0 30px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
.code-input { |
||||||
|
flex: 1; |
||||||
|
font-size: 29px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.code-placeholder { |
||||||
|
color: #666666; |
||||||
|
} |
||||||
|
|
||||||
|
.scan-icon { |
||||||
|
width: 41px; |
||||||
|
height: 41px; |
||||||
|
flex-shrink: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 券类型选项卡 |
||||||
|
.coupon-tabs { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
.tabs-left { |
||||||
|
display: flex; |
||||||
|
gap: 40px; |
||||||
|
|
||||||
|
.tab-item { |
||||||
|
position: relative; |
||||||
|
padding-bottom: 10px; |
||||||
|
|
||||||
|
.tab-text { |
||||||
|
font-size: 29px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
.tab-text { |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.tab-indicator { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
height: 6px; |
||||||
|
background-color: #01CA68; |
||||||
|
border-radius: 3px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.tabs-right { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 8px; |
||||||
|
|
||||||
|
.total-text { |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
|
||||||
|
.arrow-text { |
||||||
|
font-size: 32px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 券列表 |
||||||
|
.coupon-list { |
||||||
|
.coupon-item { |
||||||
|
position: relative; |
||||||
|
background-color: #2A2A2A; |
||||||
|
border-radius: 12px; |
||||||
|
margin-bottom: 20px; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
// 左上角标签 |
||||||
|
.coupon-tag { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
background-color: transparent; |
||||||
|
border: 2px solid #FF6B00; |
||||||
|
border-top: none; |
||||||
|
border-left: none; |
||||||
|
color: #FF6B00; |
||||||
|
font-size: 22px; |
||||||
|
padding: 4px 12px; |
||||||
|
border-bottom-right-radius: 12px; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
// 券主体 |
||||||
|
.coupon-main { |
||||||
|
display: flex; |
||||||
|
padding: 30px; |
||||||
|
gap: 20px; |
||||||
|
|
||||||
|
// 左侧:时长和券类型 |
||||||
|
.coupon-left { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
width: 150px; |
||||||
|
flex-shrink: 0; |
||||||
|
padding-top: 40px; // 为左上角标签留空间 |
||||||
|
|
||||||
|
.coupon-duration-wrapper { |
||||||
|
display: flex; |
||||||
|
align-items: baseline; |
||||||
|
gap: 4px; |
||||||
|
margin-bottom: 12px; |
||||||
|
|
||||||
|
.coupon-duration { |
||||||
|
font-size: 50px; |
||||||
|
color: #FF6B00; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.coupon-unit { |
||||||
|
font-size: 25px; |
||||||
|
color: #FF6B00; |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.coupon-type { |
||||||
|
font-size: 29px; |
||||||
|
color: #999999; |
||||||
|
line-height: 1.2; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 右侧:信息区域 |
||||||
|
.coupon-right { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
gap: 8px; |
||||||
|
min-width: 0; |
||||||
|
|
||||||
|
// 标题行:标题 + 选择按钮 |
||||||
|
.title-row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
gap: 12px; |
||||||
|
|
||||||
|
.coupon-title { |
||||||
|
flex: 1; |
||||||
|
font-size: 29px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: 500; |
||||||
|
line-height: 1.4; |
||||||
|
min-width: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.select-btn { |
||||||
|
width: 44px; |
||||||
|
height: 44px; |
||||||
|
border: 2px solid #666666; |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
flex-shrink: 0; |
||||||
|
|
||||||
|
&.selected { |
||||||
|
background-color: #01CA68; |
||||||
|
border-color: #01CA68; |
||||||
|
|
||||||
|
.check-icon { |
||||||
|
font-size: 28px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.coupon-expire { |
||||||
|
font-size: 23px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
|
||||||
|
.coupon-desc { |
||||||
|
font-size: 23px; |
||||||
|
color: #FF6B00; |
||||||
|
line-height: 1.5; |
||||||
|
white-space: pre-line; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 详情区域 |
||||||
|
.coupon-details-section { |
||||||
|
padding: 0 30px 30px; |
||||||
|
border-top: 1px dashed #3A3A3A; |
||||||
|
padding-top: 20px; |
||||||
|
|
||||||
|
.detail-row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
gap: 12px; |
||||||
|
margin-bottom: 8px; |
||||||
|
|
||||||
|
.detail-text { |
||||||
|
flex: 1; |
||||||
|
font-size: 23px; |
||||||
|
color: #999999; |
||||||
|
line-height: 1.8; |
||||||
|
} |
||||||
|
|
||||||
|
.toggle-text { |
||||||
|
font-size: 20px; |
||||||
|
color: #999999; |
||||||
|
flex-shrink: 0; |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.detail-text { |
||||||
|
display: block; |
||||||
|
font-size: 23px; |
||||||
|
color: #999999; |
||||||
|
line-height: 1.8; |
||||||
|
margin-bottom: 8px; |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 底部提示 |
||||||
|
.end-tip { |
||||||
|
display: block; |
||||||
|
text-align: center; |
||||||
|
font-size: 25px; |
||||||
|
color: #666666; |
||||||
|
padding: 40px 0 60px; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 底部固定按钮 |
||||||
|
.footer-bar { |
||||||
|
position: fixed; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
padding: 20px 30px; |
||||||
|
padding-bottom: calc(20px + env(safe-area-inset-bottom)); |
||||||
|
background-color: #121212; |
||||||
|
box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.3); |
||||||
|
|
||||||
|
.exchange-btn { |
||||||
|
width: 100%; |
||||||
|
height: 90px; |
||||||
|
background-color: #01CA68; |
||||||
|
border-radius: 50px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
|
||||||
|
.exchange-text { |
||||||
|
font-size: 33px; |
||||||
|
color: #FFFFFF; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,307 @@ |
|||||||
|
/** |
||||||
|
* 团购券开台页面 |
||||||
|
*/ |
||||||
|
import { View, Text, Image, Input } from '@tarojs/components' |
||||||
|
import Taro, { useLoad } from '@tarojs/taro' |
||||||
|
import { useState } from 'react' |
||||||
|
import './index.scss' |
||||||
|
|
||||||
|
// 使用本地图片资源
|
||||||
|
const phoneIcon = require('../startTable/images/phone.png') |
||||||
|
const scanIcon = require('./images/scanIconIn.png') |
||||||
|
|
||||||
|
// 券类型枚举
|
||||||
|
enum CouponType { |
||||||
|
THIRD_PARTY = 'third_party', |
||||||
|
ACTIVITY = 'activity', |
||||||
|
} |
||||||
|
|
||||||
|
// 券数据接口
|
||||||
|
interface Coupon { |
||||||
|
id: number |
||||||
|
type: string // '团八' | '黑八'
|
||||||
|
duration: string |
||||||
|
couponType: string // '活动抵时券' | '抵时券'
|
||||||
|
title: string |
||||||
|
expireDate: string |
||||||
|
description: string |
||||||
|
details: string[] |
||||||
|
expanded: boolean |
||||||
|
} |
||||||
|
|
||||||
|
const CouponStart = () => { |
||||||
|
const [couponCode, setCouponCode] = useState('') // 券码
|
||||||
|
const [selectedCouponType, setSelectedCouponType] = useState<CouponType>(CouponType.THIRD_PARTY) |
||||||
|
const [selectedCouponId, setSelectedCouponId] = useState<number>(1) // 选中的券ID
|
||||||
|
|
||||||
|
// 券列表数据
|
||||||
|
const [coupons, setCoupons] = useState<Coupon[]>([ |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
type: '团八', |
||||||
|
duration: '20', |
||||||
|
couponType: '活动抵时券', |
||||||
|
title: '20分钟通用券(体验券)', |
||||||
|
expireDate: '2025-10-01 16:21', |
||||||
|
description: '需要交押金,超时扣押金\n单笔满40分钟可减免20分钟', |
||||||
|
details: ['不限时段,全天可用', '适用类型:中八', '每桌只单限用1张'], |
||||||
|
expanded: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 2, |
||||||
|
type: '黑八', |
||||||
|
duration: '180', |
||||||
|
couponType: '抵时券', |
||||||
|
title: '自助中式台球3小时59.9元体验券', |
||||||
|
expireDate: '2025-11-01 09:00', |
||||||
|
description: '', |
||||||
|
details: ['不限时段,全天可用'], |
||||||
|
expanded: false, |
||||||
|
}, |
||||||
|
]) |
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
console.log('团购券开台页面加载') |
||||||
|
}) |
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const handlePhoneCall = () => { |
||||||
|
Taro.makePhoneCall({ |
||||||
|
phoneNumber: '100-666-XXXX', |
||||||
|
}).catch((err) => { |
||||||
|
console.error('拨打电话失败:', err) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 扫描券码
|
||||||
|
const handleScanCode = () => { |
||||||
|
Taro.scanCode({ |
||||||
|
scanType: ['qrCode', 'barCode'], |
||||||
|
}).then((res) => { |
||||||
|
setCouponCode(res.result) |
||||||
|
}).catch((err) => { |
||||||
|
console.error('扫码失败:', err) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 切换券类型
|
||||||
|
const handleSwitchType = (type: CouponType) => { |
||||||
|
setSelectedCouponType(type) |
||||||
|
} |
||||||
|
|
||||||
|
// 选择券
|
||||||
|
const handleSelectCoupon = (id: number) => { |
||||||
|
setSelectedCouponId(id) |
||||||
|
} |
||||||
|
|
||||||
|
// 展开/收起券详情
|
||||||
|
const handleToggleExpand = (id: number) => { |
||||||
|
setCoupons(prev => prev.map(coupon => |
||||||
|
coupon.id === id ? { ...coupon, expanded: !coupon.expanded } : coupon |
||||||
|
)) |
||||||
|
} |
||||||
|
|
||||||
|
// 兑换开台
|
||||||
|
const handleExchange = () => { |
||||||
|
if (!selectedCouponId) { |
||||||
|
Taro.showToast({ |
||||||
|
title: '请选择一张券', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
console.log('兑换开台,选中券ID:', selectedCouponId) |
||||||
|
Taro.showToast({ |
||||||
|
title: '功能开发中', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="coupon-start-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>[中式台球]来力.山岩-A03/3号球桌</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 价格信息 */} |
||||||
|
<View className="price-info"> |
||||||
|
<View className="price-item"> |
||||||
|
<Text className="price-value">¥28.80</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 ¥20.00</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 价格时段 */} |
||||||
|
<View className="time-period"> |
||||||
|
<Text>价格时段:00:00-24:00</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 使用说明 */} |
||||||
|
<View className="instruction-box"> |
||||||
|
<View className="instruction-item"> |
||||||
|
<View className="number-circle"> |
||||||
|
<Text className="number">❶</Text> |
||||||
|
</View> |
||||||
|
<Text className="instruction-text">打开美团、抖音、大众点评或快手等</Text> |
||||||
|
</View> |
||||||
|
<View className="instruction-item"> |
||||||
|
<View className="number-circle"> |
||||||
|
<Text className="number">❷</Text> |
||||||
|
</View> |
||||||
|
<Text className="instruction-text">长按复制券码贴到对方输入框</Text> |
||||||
|
</View> |
||||||
|
<View className="instruction-item"> |
||||||
|
<View className="number-circle"> |
||||||
|
<Text className="number">❸</Text> |
||||||
|
</View> |
||||||
|
<Text className="instruction-text">点击[兑换],成功兑换团购券</Text> |
||||||
|
</View> |
||||||
|
<Text className="instruction-note">注:也可以通过扫团购券码完成兑换</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 券码输入框 */} |
||||||
|
<View className="code-input-box"> |
||||||
|
<Input |
||||||
|
className="code-input" |
||||||
|
placeholder="请输入券码" |
||||||
|
placeholderClass="code-placeholder" |
||||||
|
value={couponCode} |
||||||
|
onInput={(e) => setCouponCode(e.detail.value)} |
||||||
|
/> |
||||||
|
<Image |
||||||
|
className="scan-icon" |
||||||
|
src={scanIcon} |
||||||
|
mode="aspectFit" |
||||||
|
onClick={handleScanCode} |
||||||
|
/> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 券类型选项卡 */} |
||||||
|
<View className="coupon-tabs"> |
||||||
|
<View className="tabs-left"> |
||||||
|
<View |
||||||
|
className={`tab-item ${selectedCouponType === CouponType.THIRD_PARTY ? 'active' : ''}`} |
||||||
|
onClick={() => handleSwitchType(CouponType.THIRD_PARTY)} |
||||||
|
> |
||||||
|
<Text className="tab-text">第三方卡券</Text> |
||||||
|
{selectedCouponType === CouponType.THIRD_PARTY && <View className="tab-indicator" />} |
||||||
|
</View> |
||||||
|
<View |
||||||
|
className={`tab-item ${selectedCouponType === CouponType.ACTIVITY ? 'active' : ''}`} |
||||||
|
onClick={() => handleSwitchType(CouponType.ACTIVITY)} |
||||||
|
> |
||||||
|
<Text className="tab-text">活动卡券</Text> |
||||||
|
{selectedCouponType === CouponType.ACTIVITY && <View className="tab-indicator" />} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
<View className="tabs-right"> |
||||||
|
<Text className="total-text">共{coupons.length}张</Text> |
||||||
|
<Text className="arrow-text">›</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 券列表 */} |
||||||
|
<View className="coupon-list"> |
||||||
|
{coupons.map((coupon) => ( |
||||||
|
<View key={coupon.id} className="coupon-item"> |
||||||
|
{/* 左上角标签 */} |
||||||
|
<View className="coupon-tag">{coupon.type}</View> |
||||||
|
|
||||||
|
<View className="coupon-main" onClick={() => handleSelectCoupon(coupon.id)}> |
||||||
|
{/* 左侧:时长和券类型 */} |
||||||
|
<View className="coupon-left"> |
||||||
|
<View className="coupon-duration-wrapper"> |
||||||
|
<Text className="coupon-duration">{coupon.duration}</Text> |
||||||
|
<Text className="coupon-unit">分钟</Text> |
||||||
|
</View> |
||||||
|
<Text className="coupon-type">{coupon.couponType}</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 右侧:信息区域 */} |
||||||
|
<View className="coupon-right"> |
||||||
|
{/* 标题行:标题 + 选择按钮 */} |
||||||
|
<View className="title-row"> |
||||||
|
<Text className="coupon-title">{coupon.title}</Text> |
||||||
|
<View |
||||||
|
className={`select-btn ${selectedCouponId === coupon.id ? 'selected' : ''}`} |
||||||
|
onClick={(e) => { |
||||||
|
e.stopPropagation() |
||||||
|
handleSelectCoupon(coupon.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
{selectedCouponId === coupon.id && <Text className="check-icon">✓</Text>} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 有效期 */} |
||||||
|
<Text className="coupon-expire">有效日期至:{coupon.expireDate}</Text> |
||||||
|
|
||||||
|
{/* 描述 */} |
||||||
|
{coupon.description && <Text className="coupon-desc">{coupon.description}</Text>} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 详情区域 */} |
||||||
|
<View className="coupon-details-section"> |
||||||
|
{/* 第一条详情 + 展开/收起按钮 */} |
||||||
|
{coupon.details.length > 0 && ( |
||||||
|
<View className="detail-row"> |
||||||
|
<Text className="detail-text">{coupon.details[0]}</Text> |
||||||
|
<Text |
||||||
|
className="toggle-text" |
||||||
|
onClick={() => handleToggleExpand(coupon.id)} |
||||||
|
> |
||||||
|
{coupon.expanded ? '∧' : '∨'} |
||||||
|
</Text> |
||||||
|
</View> |
||||||
|
)} |
||||||
|
|
||||||
|
{/* 展开时显示其余详情 */} |
||||||
|
{coupon.expanded && coupon.details.slice(1).map((detail, index) => ( |
||||||
|
<Text key={index} className="detail-text">{detail}</Text> |
||||||
|
))} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
))} |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 底部提示 */} |
||||||
|
<Text className="end-tip">到底了~</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 底部固定按钮 */} |
||||||
|
<View className="footer-bar"> |
||||||
|
<View className="exchange-btn" onClick={handleExchange}> |
||||||
|
<Text className="exchange-text">兑换开台</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CouponStart |
||||||
Loading…
Reference in new issue