4 changed files with 756 additions and 0 deletions
@ -0,0 +1,397 @@ |
|||||||
|
/** |
||||||
|
* 预约开台页面样式 |
||||||
|
*/ |
||||||
|
.appointment_start_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 { |
||||||
|
margin-bottom: 20px; |
||||||
|
|
||||||
|
.store_name { |
||||||
|
font-size: 25px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.table_title_row { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 15px; |
||||||
|
margin: 24px 0 26px; |
||||||
|
|
||||||
|
.table_title { |
||||||
|
font-weight: bold; |
||||||
|
font-size: 42px; |
||||||
|
color: #FFFFFF; |
||||||
|
line-height: 1.4; |
||||||
|
} |
||||||
|
|
||||||
|
.status_info { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
.status_text { |
||||||
|
font-size: 28px; |
||||||
|
font-weight: 500; |
||||||
|
|
||||||
|
&.using { |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.status_tip { |
||||||
|
font-size: 25px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.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: #00A6FF; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 预约信息卡片 |
||||||
|
.appointment_card { |
||||||
|
background-color: #21212A; |
||||||
|
border-radius: 13px; |
||||||
|
padding: 30px; |
||||||
|
margin-bottom: 30px; |
||||||
|
|
||||||
|
// 行项目 |
||||||
|
.row_item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 20px 0; |
||||||
|
border-bottom: 1PX solid #2A2A35; |
||||||
|
|
||||||
|
&:first-child { |
||||||
|
padding-top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
border-bottom: none; |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.row_label { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.row_right { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.row_value { |
||||||
|
font-size: 31px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
.row_arrow { |
||||||
|
font-size: 28px; |
||||||
|
color: #E6E6E6; |
||||||
|
} |
||||||
|
|
||||||
|
// 时长步进器 |
||||||
|
.duration_stepper { |
||||||
|
--stepper-input-width: 80px; |
||||||
|
--stepper-input-height: 56px; |
||||||
|
--stepper-input-font-size: 31px; |
||||||
|
--stepper-input-color: #FFFFFF; |
||||||
|
--stepper-input-background-color: #21212A; |
||||||
|
--stepper-circular-decrease-button-color: #FFFFFF; |
||||||
|
--stepper-circular-decrease-button-background-color: #565B66; |
||||||
|
--stepper-circular-decrease-button-border-color: #565B66; |
||||||
|
--stepper-circular-increase-button-color: #FFFFFF; |
||||||
|
--stepper-circular-increase-button-background-color: #565B66; |
||||||
|
--stepper-circular-increase-button-border-color: #565B66; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 时间段展示区域 |
||||||
|
.time_slots_section { |
||||||
|
padding: 20px 0; |
||||||
|
border-bottom: 1PX solid #2A2A35; |
||||||
|
|
||||||
|
.time_slots_scroll { |
||||||
|
width: 100%; |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
|
||||||
|
.time_slots { |
||||||
|
display: inline-flex; |
||||||
|
gap: 0; |
||||||
|
|
||||||
|
.time_slot { |
||||||
|
width: 50px; |
||||||
|
height: 40px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
|
||||||
|
.slot_text { |
||||||
|
font-size: 23px; |
||||||
|
color: #666666; |
||||||
|
} |
||||||
|
|
||||||
|
// 已预约状态 |
||||||
|
&.reserved { |
||||||
|
.slot_text { |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
|
||||||
|
// 底部绿色指示条 |
||||||
|
position: relative; |
||||||
|
|
||||||
|
&::after { |
||||||
|
content: ''; |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 50%; |
||||||
|
transform: translateX(-50%); |
||||||
|
width: 30px; |
||||||
|
height: 4px; |
||||||
|
background-color: #03C175; |
||||||
|
border-radius: 2px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 未预约状态底部灰色指示条 |
||||||
|
&:not(.reserved) { |
||||||
|
position: relative; |
||||||
|
|
||||||
|
&::after { |
||||||
|
content: ''; |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 50%; |
||||||
|
transform: translateX(-50%); |
||||||
|
width: 30px; |
||||||
|
height: 4px; |
||||||
|
background-color: #3A3D42; |
||||||
|
border-radius: 2px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 图例 |
||||||
|
.legend { |
||||||
|
display: flex; |
||||||
|
gap: 30px; |
||||||
|
margin-top: 20px; |
||||||
|
|
||||||
|
.legend_item { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
gap: 10px; |
||||||
|
|
||||||
|
.legend_dot { |
||||||
|
width: 20px; |
||||||
|
height: 6px; |
||||||
|
border-radius: 3px; |
||||||
|
|
||||||
|
&.reserved { |
||||||
|
background-color: #03C175; |
||||||
|
} |
||||||
|
|
||||||
|
&.available { |
||||||
|
background-color: #3A3D42; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.legend_text { |
||||||
|
font-size: 23px; |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 支付方式 |
||||||
|
.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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// DatetimePicker 样式覆盖 |
||||||
|
:global { |
||||||
|
.taroify-datetime-picker { |
||||||
|
background-color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.taroify-picker__toolbar { |
||||||
|
height: 88px; |
||||||
|
} |
||||||
|
|
||||||
|
.taroify-picker__cancel, |
||||||
|
.taroify-picker__confirm { |
||||||
|
font-size: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.taroify-picker__cancel { |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
|
||||||
|
.taroify-picker__confirm { |
||||||
|
color: #03C175; |
||||||
|
} |
||||||
|
|
||||||
|
.taroify-picker__title { |
||||||
|
font-size: 32px; |
||||||
|
color: #333333; |
||||||
|
font-weight: 500; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,348 @@ |
|||||||
|
/** |
||||||
|
* 预约开台页面 |
||||||
|
*/ |
||||||
|
import { View, Text, Image, ScrollView } from '@tarojs/components' |
||||||
|
import Taro, { useLoad } from '@tarojs/taro' |
||||||
|
import { useState, useMemo } from 'react' |
||||||
|
import { Stepper, Popup, DatetimePicker } from '@taroify/core' |
||||||
|
import { Arrow } from '@taroify/icons' |
||||||
|
import './index.scss' |
||||||
|
|
||||||
|
// 使用本地图片资源
|
||||||
|
const phoneIcon = require('../../pageScan/startTable/images/phone.png') |
||||||
|
|
||||||
|
// 生成24小时时间段
|
||||||
|
const generateHours = () => { |
||||||
|
return Array.from({ length: 24 }, (_, i) => ({ |
||||||
|
hour: i, |
||||||
|
label: i.toString().padStart(2, '0') |
||||||
|
})) |
||||||
|
} |
||||||
|
|
||||||
|
const AppointmentStart = () => { |
||||||
|
// 日期相关
|
||||||
|
const [selectedDate, setSelectedDate] = useState(new Date()) |
||||||
|
const [showDatePicker, setShowDatePicker] = useState(false) |
||||||
|
const [tempDate, setTempDate] = useState(new Date()) |
||||||
|
|
||||||
|
// 时间相关
|
||||||
|
const [startHour, setStartHour] = useState(9) // 预约开始小时
|
||||||
|
const [startMinute, setStartMinute] = useState(0) // 预约开始分钟
|
||||||
|
const [duration, setDuration] = useState(3) // 时长(小时)
|
||||||
|
const [showStartTimePicker, setShowStartTimePicker] = useState(false) |
||||||
|
const [tempStartTime, setTempStartTime] = useState(new Date()) |
||||||
|
|
||||||
|
// 支付方式
|
||||||
|
const [paymentMethod] = useState('微信支付') |
||||||
|
|
||||||
|
// 模拟已预约的时间段(小时)
|
||||||
|
const reservedHours = [9, 10, 11] |
||||||
|
|
||||||
|
// 24小时列表
|
||||||
|
const hours = generateHours() |
||||||
|
|
||||||
|
useLoad(() => { |
||||||
|
console.log('预约开台页面加载') |
||||||
|
}) |
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const handlePhoneCall = () => { |
||||||
|
Taro.makePhoneCall({ |
||||||
|
phoneNumber: '100-666-XXXX', |
||||||
|
}).catch((err) => { |
||||||
|
console.error('拨打电话失败:', err) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 格式化日期显示
|
||||||
|
const formatDateDisplay = (date: Date) => { |
||||||
|
const year = date.getFullYear() |
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, '0') |
||||||
|
const day = date.getDate().toString().padStart(2, '0') |
||||||
|
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] |
||||||
|
const weekDay = weekDays[date.getDay()] |
||||||
|
return `${year}-${month}-${day} (${weekDay})` |
||||||
|
} |
||||||
|
|
||||||
|
// 格式化时间显示
|
||||||
|
const formatTimeDisplay = (hour: number, minute: number) => { |
||||||
|
return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}` |
||||||
|
} |
||||||
|
|
||||||
|
// 计算结束时间
|
||||||
|
const endTime = useMemo(() => { |
||||||
|
let endHour = startHour + duration |
||||||
|
const endMinute = startMinute |
||||||
|
if (endHour >= 24) { |
||||||
|
endHour = endHour - 24 |
||||||
|
} |
||||||
|
return formatTimeDisplay(endHour, endMinute) |
||||||
|
}, [startHour, startMinute, duration]) |
||||||
|
|
||||||
|
// 计算支付金额
|
||||||
|
const totalAmount = useMemo(() => { |
||||||
|
return (duration * 60).toFixed(2) |
||||||
|
}, [duration]) |
||||||
|
|
||||||
|
// 打开日期选择器
|
||||||
|
const handleOpenDatePicker = () => { |
||||||
|
setTempDate(selectedDate) |
||||||
|
setShowDatePicker(true) |
||||||
|
} |
||||||
|
|
||||||
|
// 确认日期选择
|
||||||
|
const handleConfirmDate = (value: Date) => { |
||||||
|
setSelectedDate(value) |
||||||
|
setShowDatePicker(false) |
||||||
|
} |
||||||
|
|
||||||
|
// 取消日期选择
|
||||||
|
const handleCancelDate = () => { |
||||||
|
setShowDatePicker(false) |
||||||
|
} |
||||||
|
|
||||||
|
// 打开开始时间选择器
|
||||||
|
const handleOpenStartTimePicker = () => { |
||||||
|
const time = new Date() |
||||||
|
time.setHours(startHour) |
||||||
|
time.setMinutes(startMinute) |
||||||
|
setTempStartTime(time) |
||||||
|
setShowStartTimePicker(true) |
||||||
|
} |
||||||
|
|
||||||
|
// 确认开始时间选择
|
||||||
|
const handleConfirmStartTime = (value: Date) => { |
||||||
|
setStartHour(value.getHours()) |
||||||
|
setStartMinute(value.getMinutes()) |
||||||
|
setShowStartTimePicker(false) |
||||||
|
} |
||||||
|
|
||||||
|
// 取消开始时间选择
|
||||||
|
const handleCancelStartTime = () => { |
||||||
|
setShowStartTimePicker(false) |
||||||
|
} |
||||||
|
|
||||||
|
// 时长变化
|
||||||
|
const handleDurationChange = (value: number) => { |
||||||
|
setDuration(value) |
||||||
|
} |
||||||
|
|
||||||
|
// 选择支付方式
|
||||||
|
const handleSelectPayment = () => { |
||||||
|
Taro.showToast({ |
||||||
|
title: '暂时只支持微信支付', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 立即预约
|
||||||
|
const handleConfirmAppointment = () => { |
||||||
|
console.log('立即预约') |
||||||
|
Taro.showToast({ |
||||||
|
title: '功能开发中', |
||||||
|
icon: 'none', |
||||||
|
duration: 2000 |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
// 判断时间段是否已预约
|
||||||
|
const isReserved = (hour: number) => { |
||||||
|
return reservedHours.includes(hour) |
||||||
|
} |
||||||
|
|
||||||
|
// 计算最大可选日期(30天后)
|
||||||
|
const maxDate = useMemo(() => { |
||||||
|
const date = new Date() |
||||||
|
date.setDate(date.getDate() + 30) |
||||||
|
return date |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="appointment_start_page"> |
||||||
|
{/* 内容区域 */} |
||||||
|
<View className="content_area"> |
||||||
|
{/* 台球桌信息卡片 */} |
||||||
|
<View className="table_card"> |
||||||
|
{/* 顶部:店名 */} |
||||||
|
<View className="card_header"> |
||||||
|
<Text className="store_name">北京黑八大师联盟球厅店</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 台球桌标题和状态 */} |
||||||
|
<View className="table_title_row"> |
||||||
|
<Text className="table_title">[棋牌]Q01号</Text> |
||||||
|
<View className="status_info"> |
||||||
|
<Text className="status_text using">使用中</Text> |
||||||
|
<Text className="status_tip">(预计08:00结束)</Text> |
||||||
|
</View> |
||||||
|
</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="appointment_card"> |
||||||
|
{/* 日期选择 */} |
||||||
|
<View className="row_item" onClick={handleOpenDatePicker}> |
||||||
|
<Text className="row_label">日期</Text> |
||||||
|
<View className="row_right"> |
||||||
|
<Text className="row_value">{formatDateDisplay(selectedDate)}</Text> |
||||||
|
<Arrow className="row_arrow" /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 时间段展示 */} |
||||||
|
<View className="time_slots_section"> |
||||||
|
<ScrollView className="time_slots_scroll" scrollX> |
||||||
|
<View className="time_slots"> |
||||||
|
{hours.map((item) => ( |
||||||
|
<View |
||||||
|
key={item.hour} |
||||||
|
className={`time_slot ${isReserved(item.hour) ? 'reserved' : ''}`} |
||||||
|
> |
||||||
|
<Text className="slot_text">{item.label}</Text> |
||||||
|
</View> |
||||||
|
))} |
||||||
|
</View> |
||||||
|
</ScrollView> |
||||||
|
<View className="legend"> |
||||||
|
<View className="legend_item"> |
||||||
|
<View className="legend_dot reserved" /> |
||||||
|
<Text className="legend_text">已预约时段</Text> |
||||||
|
</View> |
||||||
|
<View className="legend_item"> |
||||||
|
<View className="legend_dot available" /> |
||||||
|
<Text className="legend_text">可预约时段</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 预约开始时间 */} |
||||||
|
<View className="row_item" onClick={handleOpenStartTimePicker}> |
||||||
|
<Text className="row_label">预约开始</Text> |
||||||
|
<View className="row_right"> |
||||||
|
<Text className="row_value">{formatTimeDisplay(startHour, startMinute)}</Text> |
||||||
|
<Arrow className="row_arrow" /> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 选择时长 */} |
||||||
|
<View className="row_item"> |
||||||
|
<Text className="row_label">选择时长(小时)</Text> |
||||||
|
<Stepper |
||||||
|
value={duration} |
||||||
|
min={1} |
||||||
|
max={12} |
||||||
|
step={1} |
||||||
|
onChange={handleDurationChange} |
||||||
|
shape="circular" |
||||||
|
size="27px" |
||||||
|
className="duration_stepper" |
||||||
|
/> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 预约结束时间 */} |
||||||
|
<View className="row_item"> |
||||||
|
<Text className="row_label">预约结束</Text> |
||||||
|
<Text className="row_value">{endTime}</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">温馨提示:</Text> |
||||||
|
<Text className="tips_text">1. 预约桌台成功后,距离 预约开始>1小时 可退回预约金,预约开始≤1小时 则无法取消;</Text> |
||||||
|
<Text className="tips_text">2. 迟到则按照原本订单结束时间结束订单。</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">{totalAmount}</Text> |
||||||
|
</View> |
||||||
|
<View className="confirm_btn" onClick={handleConfirmAppointment}> |
||||||
|
<Text className="confirm_text">立即预约</Text> |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
|
||||||
|
{/* 日期选择器弹窗 */} |
||||||
|
<Popup |
||||||
|
open={showDatePicker} |
||||||
|
placement="bottom" |
||||||
|
rounded |
||||||
|
onClose={handleCancelDate} |
||||||
|
> |
||||||
|
<DatetimePicker |
||||||
|
type="date" |
||||||
|
value={tempDate} |
||||||
|
min={new Date()} |
||||||
|
max={maxDate} |
||||||
|
onChange={setTempDate} |
||||||
|
onConfirm={handleConfirmDate} |
||||||
|
onCancel={handleCancelDate} |
||||||
|
> |
||||||
|
<DatetimePicker.Toolbar> |
||||||
|
<DatetimePicker.Button onClick={handleCancelDate}>取消</DatetimePicker.Button> |
||||||
|
<DatetimePicker.Title>{formatDateDisplay(tempDate)}</DatetimePicker.Title> |
||||||
|
<DatetimePicker.Button onClick={() => handleConfirmDate(tempDate)}>确定</DatetimePicker.Button> |
||||||
|
</DatetimePicker.Toolbar> |
||||||
|
</DatetimePicker> |
||||||
|
</Popup> |
||||||
|
|
||||||
|
{/* 开始时间选择器弹窗 */} |
||||||
|
<Popup |
||||||
|
open={showStartTimePicker} |
||||||
|
placement="bottom" |
||||||
|
rounded |
||||||
|
onClose={handleCancelStartTime} |
||||||
|
> |
||||||
|
<DatetimePicker |
||||||
|
type="hour-minute" |
||||||
|
value={tempStartTime} |
||||||
|
onChange={setTempStartTime} |
||||||
|
onConfirm={handleConfirmStartTime} |
||||||
|
onCancel={handleCancelStartTime} |
||||||
|
> |
||||||
|
<DatetimePicker.Toolbar> |
||||||
|
<DatetimePicker.Button onClick={handleCancelStartTime}>取消</DatetimePicker.Button> |
||||||
|
<DatetimePicker.Title>选择开始时间</DatetimePicker.Title> |
||||||
|
<DatetimePicker.Button onClick={() => handleConfirmStartTime(tempStartTime)}>确定</DatetimePicker.Button> |
||||||
|
</DatetimePicker.Toolbar> |
||||||
|
</DatetimePicker> |
||||||
|
</Popup> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default AppointmentStart |
||||||
Loading…
Reference in new issue