diff --git a/src/app.config.ts b/src/app.config.ts index 7bb193d..1abd25d 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -15,6 +15,7 @@ export default defineAppConfig({ pages: [ 'mapStore/index', // 地图找店页面 'reservation/index', // 预定页面 + 'appointmentStart/index', // 预约开台页面 ] }, { diff --git a/src/pageStore/appointmentStart/index.scss b/src/pageStore/appointmentStart/index.scss new file mode 100644 index 0000000..3bc2d6a --- /dev/null +++ b/src/pageStore/appointmentStart/index.scss @@ -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; + } + } +} diff --git a/src/pageStore/appointmentStart/index.tsx b/src/pageStore/appointmentStart/index.tsx new file mode 100644 index 0000000..d5b642e --- /dev/null +++ b/src/pageStore/appointmentStart/index.tsx @@ -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 ( + + {/* 内容区域 */} + + {/* 台球桌信息卡片 */} + + {/* 顶部:店名 */} + + 北京黑八大师联盟球厅店 + + + {/* 台球桌标题和状态 */} + + [棋牌]Q01号 + + 使用中 + (预计08:00结束) + + + + {/* 价格信息 */} + + + ¥60.00 + /小时, + + + 押金 + ¥100.00 + + + VIP ¥50.00 + + + + {/* 价格时段 */} + + 价格时段:00:00-24:00 + + + + {/* 预约信息卡片 */} + + {/* 日期选择 */} + + 日期 + + {formatDateDisplay(selectedDate)} + + + + + {/* 时间段展示 */} + + + + {hours.map((item) => ( + + {item.label} + + ))} + + + + + + 已预约时段 + + + + 可预约时段 + + + + + {/* 预约开始时间 */} + + 预约开始 + + {formatTimeDisplay(startHour, startMinute)} + + + + + {/* 选择时长 */} + + 选择时长(小时) + + + + {/* 预约结束时间 */} + + 预约结束 + {endTime} + + + + {/* 支付方式 */} + + 支付方式 + + {paymentMethod} + + + + + {/* 温馨提示 */} + + 温馨提示: + 1. 预约桌台成功后,距离 预约开始>1小时 可退回预约金,预约开始≤1小时 则无法取消; + 2. 迟到则按照原本订单结束时间结束订单。 + + + + {/* 底部固定区域 */} + + + 需支付 + ¥ + {totalAmount} + + + 立即预约 + + + + {/* 日期选择器弹窗 */} + + + + 取消 + {formatDateDisplay(tempDate)} + handleConfirmDate(tempDate)}>确定 + + + + + {/* 开始时间选择器弹窗 */} + + + + 取消 + 选择开始时间 + handleConfirmStartTime(tempStartTime)}>确定 + + + + + ) +} + +export default AppointmentStart diff --git a/src/pages/scan/index.tsx b/src/pages/scan/index.tsx index ecf872f..da553ec 100644 --- a/src/pages/scan/index.tsx +++ b/src/pages/scan/index.tsx @@ -79,6 +79,13 @@ const ScanIndex = observer(() => { }) } + // 预约开台 + const handleAppointmentStart = () => { + Taro.navigateTo({ + url: '/pageStore/appointmentStart/index' + }) + } + return ( @@ -91,6 +98,9 @@ const ScanIndex = observer(() => { +