From e0f5f7d9e2d1524683e34bc5d9ed2a6eb4b1d24f Mon Sep 17 00:00:00 2001 From: DU Date: Thu, 22 Jan 2026 00:55:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=99=E9=A2=9D=E5=85=85=E5=80=BC=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E6=98=8E=E7=BB=86=EF=BC=8C=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=20=E8=AE=A2=E5=8D=95=E8=AF=A6?= =?UTF-8?q?=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.config.ts | 3 + .../components/BalanceList.scss | 2 +- src/pagesOrder/accountBalance/index.tsx | 6 +- src/pagesOrder/recharge/index.config.ts | 5 + src/pagesOrder/recharge/index.scss | 187 ++++++++++ src/pagesOrder/recharge/index.tsx | 143 +++++++ src/pagesOrder/rechargeDetail/index.config.ts | 5 + src/pagesOrder/rechargeDetail/index.scss | 147 ++++++++ src/pagesUser/orderDetail/index.config.ts | 5 + src/pagesUser/orderDetail/index.scss | 353 ++++++++++++++++++ src/pagesUser/orderDetail/index.tsx | 230 ++++++++++++ .../orderList/components/FilterPopup.scss | 179 +++++++++ .../orderList/components/FilterPopup.tsx | 283 ++++++++++++++ src/pagesUser/orderList/index.scss | 181 ++++++++- src/pagesUser/orderList/index.tsx | 189 +++++++++- 15 files changed, 1911 insertions(+), 7 deletions(-) create mode 100644 src/pagesOrder/recharge/index.config.ts create mode 100644 src/pagesOrder/recharge/index.scss create mode 100644 src/pagesOrder/recharge/index.tsx create mode 100644 src/pagesOrder/rechargeDetail/index.config.ts create mode 100644 src/pagesOrder/rechargeDetail/index.scss create mode 100644 src/pagesUser/orderDetail/index.config.ts create mode 100644 src/pagesUser/orderDetail/index.scss create mode 100644 src/pagesUser/orderDetail/index.tsx create mode 100644 src/pagesUser/orderList/components/FilterPopup.scss create mode 100644 src/pagesUser/orderList/components/FilterPopup.tsx diff --git a/src/app.config.ts b/src/app.config.ts index f6f0f35..dc81a4f 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -22,6 +22,7 @@ export default defineAppConfig({ pages: [ 'poleStorage/index', // 存杆柜记录 'orderList/index', // 订单记录 + 'orderDetail/index', // 订单详情 'unsettledOrders/index', // 未结算账单 'goodsCons/index', // 商品消费 'helpCenter/index', // 帮助中心 @@ -49,6 +50,8 @@ export default defineAppConfig({ name: 'order-package', pages: [ 'accountBalance/index', // 账户余额 + 'recharge/index', // 余额充值 + 'rechargeDetail/index', // 充值明细 ] } ], diff --git a/src/pagesOrder/accountBalance/components/BalanceList.scss b/src/pagesOrder/accountBalance/components/BalanceList.scss index a54145c..9811f24 100644 --- a/src/pagesOrder/accountBalance/components/BalanceList.scss +++ b/src/pagesOrder/accountBalance/components/BalanceList.scss @@ -69,7 +69,7 @@ padding: 30px; display: flex; flex-direction: column; - align-items: flex-start; + align-items: center; // 金额显示 .amount-row { diff --git a/src/pagesOrder/accountBalance/index.tsx b/src/pagesOrder/accountBalance/index.tsx index c896ef5..59c9378 100644 --- a/src/pagesOrder/accountBalance/index.tsx +++ b/src/pagesOrder/accountBalance/index.tsx @@ -2,7 +2,7 @@ * 账户余额页面 */ import { View, ScrollView } from '@tarojs/components' -import { useLoad } from '@tarojs/taro' +import Taro, { useLoad } from '@tarojs/taro' import { useState } from 'react' import { Tabs } from '@taroify/core' import BalanceList from './components/BalanceList' @@ -99,7 +99,9 @@ const AccountBalance = () => { const handleRecharge = (storeId: string) => { console.log('充值', storeId) - // TODO: 跳转到充值页面 + Taro.navigateTo({ + url: '/pagesOrder/recharge/index' + }) } const handleViewCabinet = (storeId: string) => { diff --git a/src/pagesOrder/recharge/index.config.ts b/src/pagesOrder/recharge/index.config.ts new file mode 100644 index 0000000..d2b7fb7 --- /dev/null +++ b/src/pagesOrder/recharge/index.config.ts @@ -0,0 +1,5 @@ +export default definePageConfig({ + navigationBarTitleText: '余额充值', + navigationBarBackgroundColor: '#121212', + navigationBarTextStyle: 'white' +}) diff --git a/src/pagesOrder/recharge/index.scss b/src/pagesOrder/recharge/index.scss new file mode 100644 index 0000000..e45d8eb --- /dev/null +++ b/src/pagesOrder/recharge/index.scss @@ -0,0 +1,187 @@ +.recharge-page { + min-height: 100vh; + background-color: #FFFFFF; + padding-bottom: 150px; // 为底部按钮留出空间 + + // 上部分:余额卡片区域 + .balance-card-area { + background-color: #121212; + padding: 40px 30px 0; + + .store-name { + display: block; + font-size: 40px; + color: #F5C8A6; + margin-bottom: 33px; + } + + .balance-card { + background: linear-gradient(-30deg, #F0BE86 0%, #FADEB9 100%); + border-top-left-radius: 21px; + border-top-right-radius: 21px; + padding: 33px; + + .card-row { + display: flex; + align-items: center; + justify-content: space-between; + + .label { + font-size: 30px; + color: #844614; + } + + .detail-wrapper { + display: flex; + align-items: center; + gap: 5px; + + .detail-link { + font-size: 25px; + color: #844614; + } + } + } + + .amount-row { + display: flex; + align-items: baseline; + margin-top: 28px; + margin-bottom: 40px; + + .currency { + font-size: 25px; + color: #844614; + margin-right: 5px; + } + + .amount { + font-size: 40px; + font-weight: bold; + color: #844614; + } + } + + .info-row { + display: flex; + align-items: center; + justify-content: space-between; + + .info-item { + display: flex; + align-items: baseline; + + .info-text { + font-size: 25px; + color: #844614; + } + + .info-value { + font-size: 25px; + color: #844614; + } + } + } + } + } + + // 下部分:套餐和提示区域 + .packages-area { + padding: 40px 30px; + + .section-title { + display: block; + font-weight: bold; + font-size: 33px; + color: #333333; + margin-bottom: 30px; + } + + // 充值套餐网格 + .packages-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 30px; + margin-bottom: 40px; + + .package-item { + width: 211px; + height: 150px; + background: #F2F3F5; + border-radius: 13px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + box-sizing: border-box; + + .package-amount { + font-weight: bold; + font-size: 38px; + color: #333333; + } + + .package-bonus { + font-size: 29px; + color: #FF6B00; + } + + // 选中状态 + &.selected { + border: 2px solid #C77734; + + .package-amount { + color: #844614; + } + + .package-bonus { + color: #844614; + } + } + } + } + + // 温馨提示 + .tips-section { + .tips-title { + font-weight: bold; + font-size: 25px; + color: #666666; + } + + .tips-content { + font-size: 25px; + color: #666666; + line-height: 1.8; + } + } + } + + // 底部固定按钮 + .footer-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding: 30px; + background-color: #FFFFFF; + box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); + + .recharge-btn { + width: 100%; + height: 88px; + background: linear-gradient(-90deg, #F0BE86 0%, #FADEB9 100%); + border-radius: 44px; + display: flex; + align-items: center; + justify-content: center; + + .recharge-btn-text { + font-weight: bold; + font-size: 33px; + color: #844614; + } + } + } +} diff --git a/src/pagesOrder/recharge/index.tsx b/src/pagesOrder/recharge/index.tsx new file mode 100644 index 0000000..00612c2 --- /dev/null +++ b/src/pagesOrder/recharge/index.tsx @@ -0,0 +1,143 @@ +/** + * 余额充值页面 + */ +import { View, Text } from '@tarojs/components' +import Taro, { useLoad } from '@tarojs/taro' +import { useState } from 'react' +import './index.scss' +import { Arrow } from '@taroify/icons' + +// 充值套餐数据 +interface RechargePackage { + id: number + amount: number // 充值金额 + bonus: number // 赠送金额 +} + +const RechargePackages: RechargePackage[] = [ + { id: 1, amount: 100, bonus: 50 }, + { id: 2, amount: 200, bonus: 100 }, + { id: 3, amount: 300, bonus: 200 }, + { id: 4, amount: 500, bonus: 300 }, + { id: 5, amount: 800, bonus: 500 }, + { id: 6, amount: 1000, bonus: 700 }, +] + +const RechargePage = () => { + const [selectedPackageId, setSelectedPackageId] = useState(null) + const [currentBalance] = useState(28.8) // 当前余额 + + useLoad(() => { + console.log('余额充值页面加载') + }) + + // 选择套餐 + const handleSelectPackage = (id: number) => { + setSelectedPackageId(id) + } + + // 查看明细 + const handleViewDetail = () => { + Taro.navigateTo({ + url: '/pagesOrder/rechargeDetail/index' + }) + } + + // 立即充值 + const handleRecharge = () => { + if (!selectedPackageId) { + Taro.showToast({ + title: '请选择充值套餐', + icon: 'none', + duration: 2000 + }) + return + } + + const selectedPackage = RechargePackages.find(pkg => pkg.id === selectedPackageId) + if (selectedPackage) { + Taro.showToast({ + title: `充值 ¥${selectedPackage.amount}`, + icon: 'none', + duration: 2000 + }) + // TODO: 调用充值接口 + } + } + + return ( + + {/* 上部分:余额卡片区域 */} + + 北京球场风云店 + + + + 当前余额 + + 明细 + + + + + + + {currentBalance.toFixed(2)} + + + + + 充值余额: + ¥ 0.00 + + + 赠送余额: + ¥ 0.00 + + + + + + {/* 下部分:套餐和提示区域 */} + + {/* 余额充值标题 */} + 余额充值 + + {/* 充值套餐列表 */} + + {RechargePackages.map(pkg => ( + handleSelectPackage(pkg.id)} + > + 充 ¥{pkg.amount} + 赠 ¥{pkg.bonus} + + ))} + + + {/* 温馨提示 */} + + 温馨提示:{'\n'} + + 1. 您要充值的是球房商家内部会员卡,此卡只可以在充值球房商家使用,此会员卡使用规则详情,请咨询商家。{'\n'} + 该卡退、换、变更、发票等问题,请咨询商家。{'\n'} + 2. 会员卡由球房自行设定,充值内容由球房自行发布,会员卡充值优惠内容随时可能会变更。{'\n'} + 3. 售卖商品和部分商家指定桌台不可用账户余额支付。{'\n'} + (充值仅限本店台球、棋牌使用;充值后不可退款或转让。) + + + + + {/* 底部固定按钮 */} + + + 立即充值 + + + + ) +} + +export default RechargePage diff --git a/src/pagesOrder/rechargeDetail/index.config.ts b/src/pagesOrder/rechargeDetail/index.config.ts new file mode 100644 index 0000000..30ff0cc --- /dev/null +++ b/src/pagesOrder/rechargeDetail/index.config.ts @@ -0,0 +1,5 @@ +export default definePageConfig({ + navigationBarTitleText: '充值明细', + navigationBarBackgroundColor: '#FFFFFF', + navigationBarTextStyle: 'black' +}) diff --git a/src/pagesOrder/rechargeDetail/index.scss b/src/pagesOrder/rechargeDetail/index.scss new file mode 100644 index 0000000..094ebb2 --- /dev/null +++ b/src/pagesOrder/rechargeDetail/index.scss @@ -0,0 +1,147 @@ +.recharge-detail-page { + padding: 30px; + background-color: #F2F3F5; + min-height: 100vh; + + // 空数据展示 + .empty-data { + display: flex; + justify-content: center; + align-items: center; + padding: 150px 0; + + .empty-image { + width: 400px; + height: 400px; + } + } + + // 月份卡片 + .month-card { + background-color: #FFFFFF; + border-radius: 12px; + margin-bottom: 30px; + + // 月份标题行 + .month-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 36px 30px; + + .month-left { + display: flex; + align-items: center; + gap: 10px; + + .month-text { + font-size: 33px; + color: #000000; + } + + .month-arrow { + flex-shrink: 0; + } + } + + .month-right { + display: flex; + align-items: baseline; + gap: 4px; + + .amount-label { + font-size: 25px; + color: #999999; + margin-right: 8px; + } + + .amount-symbol { + font-size: 25px; + color: #000000; + } + + .amount-value { + font-size: 30px; + color: #000000; + } + } + } + + // 分割线 + .divider { + height: 1px; + background-color: #F2F3F5; + } + + // 记录列表 + .record-list { + padding: 20px; + + .record-item { + display: flex; + flex-direction: column; + gap: 20px; + + .item-row { + display: flex; + align-items: baseline; + justify-content: space-between; + + .store-name { + font-size: 33px; + color: #000000; + flex: 1; + } + + .status { + font-size: 32px; + color: #D0955E; + } + + .recharge-type { + font-size: 25px; + color: #333333; + } + + .recharge-time { + font-size: 22px; + color: #999999; + } + + .actual-pay { + display: flex; + align-items: baseline; + + .pay-label { + font-size: 22px; + color: #595959; + } + + .pay-amount { + font-size: 33px; + color: #000000; + } + } + } + } + + // item 之间的分割线 + .item-divider { + height: 1px; + background-color: #F2F3F5; + margin: 20px 0; + } + } + } + + // 到底了提示 + .list-end { + text-align: center; + padding: 40px 0; + + .end-text { + font-size: 25px; + color: #999999; + } + } +} diff --git a/src/pagesUser/orderDetail/index.config.ts b/src/pagesUser/orderDetail/index.config.ts new file mode 100644 index 0000000..4a7b3e1 --- /dev/null +++ b/src/pagesUser/orderDetail/index.config.ts @@ -0,0 +1,5 @@ +export default { + navigationBarTitleText: '订单详情', + navigationBarBackgroundColor: '#FFFFFF', + navigationBarTextStyle: 'black', +} diff --git a/src/pagesUser/orderDetail/index.scss b/src/pagesUser/orderDetail/index.scss new file mode 100644 index 0000000..43ab27e --- /dev/null +++ b/src/pagesUser/orderDetail/index.scss @@ -0,0 +1,353 @@ +.order-detail-page { + min-height: 100vh; + background-color: #F2F3F5; + padding-bottom: 30px; // 底部留白(无按钮区域) + + // 内容区域 + .content-area { + padding: 30px; + + // 台球桌信息卡片 + .table-card { + background-size: cover; + background-position: center; + background-repeat: no-repeat; + height: 190px; + border-radius: 12px; + padding: 24px; + display: flex; + flex-direction: column; + justify-content: space-between; + margin-bottom: 40px; + + // 顶部:类型和电话 + .card-header { + display: flex; + align-items: center; + justify-content: space-between; + + .table-type { + font-size: 25px; + color: #FFFFFF; + } + + .phone-box { + display: flex; + align-items: center; + gap: 8px; + + .phone-icon { + width: 28px; + height: 28px; + } + + .phone-text { + font-size: 25px; + color: #FFFFFF; + } + } + } + + // 台球桌标题和使用状态 + .table-title-row { + display: flex; + align-items: center; + gap: 20px; + + .table-title { + font-weight: bold; + font-size: 42px; + color: #FFFFFF; + line-height: 1.3; + } + + .table-status { + font-size: 42px; + color: #8B8B8B; + font-weight: bold; + line-height: 1.3; + } + } + + // 位置信息 + .location-info { + display: flex; + align-items: center; + gap: 8px; + + .location-icon { + width: 28px; + height: 28px; + } + + .location-text { + font-size: 25px; + color: #FFFFFF; + } + } + } + + // 开台订单信息卡片 + .order-info-card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 30px; + margin-bottom: 30px; + + // 顶部:开台方式和详情按钮 + .order-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 30px; + + .order-tag { + background-color: transparent; + border: 1px solid #FF6B00; + border-radius: 4px; + padding: 6px 12px; + + .tag-text { + font-size: 25px; + color: #FF6B00; + } + } + + .detail-btn { + display: flex; + align-items: center; + gap: 6px; + + .detail-text { + font-size: 25px; + color: #595959; + } + + .arrow-icon { + transition: transform 0.3s ease; + + &.expanded { + transform: rotate(180deg); + } + } + } + } + + // 订单统计 + .order-stats { + display: flex; + justify-content: space-around; + + .stat-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + + .stat-value { + font-size: 37px; + color: #000000; + font-weight: 500; + } + + .stat-label { + font-size: 25px; + color: #8D8D8D; + } + } + } + + // 收费规则 + .pricing-rules { + padding-top: 30px; + border-top: 1px solid #F2F3F5; + + .rules-content { + background-color: #F2F3F5; + border-radius: 13px; + padding: 30px; + display: flex; + flex-direction: column; + gap: 25px; + + .rules-title { + font-weight: 400; + font-size: 29px; + color: #000000; + } + + .price-row { + display: flex; + justify-content: space-between; + align-items: center; + + .price-item { + display: flex; + align-items: center; + gap: 4px; + + .price-label { + font-size: 25px; + color: #8B8B8B; + } + + .price-value { + font-size: 25px; + color: #333333; + } + } + } + } + } + } + + // 展开的详细信息卡片(支付信息、开台信息) + .info-card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 30px; + margin-bottom: 30px; + + .card-title { + font-size: 33px; + color: #000000; + font-weight: 500; + margin-bottom: 30px; + display: block; + } + + .info-row { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 0; + border-bottom: 1px solid #F2F3F5; + + &:last-child { + border-bottom: none; + } + + &.total { + padding-top: 25px; + + .info-label { + color: #8B8B8B; + } + + .info-value { + font-size: 35px; + font-weight: 500; + } + } + + &.expandable { + cursor: pointer; + } + + .info-label { + font-size: 30px; + color: #595959; + flex-shrink: 0; + } + + .info-value { + font-size: 30px; + color: #000000; + text-align: right; + flex: 1; + margin-left: 20px; + word-break: break-all; + } + + .info-value-box { + display: flex; + align-items: center; + gap: 10px; + } + + .info-desc { + font-size: 30px; + color: #8B8B8B; + } + + .info-right { + display: flex; + align-items: center; + flex: 1; + justify-content: flex-end; + + .info-desc { + font-size: 30px; + color: #8B8B8B; + flex: none; + } + + .info-value { + font-size: 30px; + color: #FF6B00; + margin-left: 16px; + margin-right: 10px; + flex: none; + text-align: left; + } + + .arrow-icon { + transition: transform 0.3s ease; + flex-shrink: 0; + + &.expanded { + transform: rotate(180deg); + } + } + } + } + + // 展开内容 + .expand-content { + background-color: #F2F3F5; + border-radius: 13px; + padding: 25px; + margin-top: 15px; + margin-bottom: 15px; + + .expand-text { + display: block; + font-size: 28px; + color: #333333; + line-height: 1.8; + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + } + + .expand-value { + display: block; + font-size: 28px; + color: #FF6B00; + line-height: 1.8; + margin-top: 10px; + } + + // 优惠券展开内容(横向布局) + &.coupon { + display: flex; + justify-content: space-between; + align-items: center; + + .expand-text { + margin-bottom: 0; + flex: 1; + } + + .expand-value { + margin-top: 0; + flex-shrink: 0; + margin-left: 20px; + } + } + } + } + } +} diff --git a/src/pagesUser/orderDetail/index.tsx b/src/pagesUser/orderDetail/index.tsx new file mode 100644 index 0000000..f75b59c --- /dev/null +++ b/src/pagesUser/orderDetail/index.tsx @@ -0,0 +1,230 @@ +/** + * 订单详情页面 + */ +import { View, Text, Image } from '@tarojs/components' +import Taro, { useLoad, useRouter } from '@tarojs/taro' +import { useState } from 'react' +import { ArrowDown } from '@taroify/icons' +import './index.scss' + +// 使用本地图片资源 +const phoneIcon = require('../../pageScan/startTable/images/phone.png') +const locationIcon = require('../../assets/icon/locationIcon.png') +const tableBgImg = require('../../pageScan/startTable/images/startBiliardCardBg.png') + +const OrderDetail = () => { + const router = useRouter() + const { orderId } = router.params as { orderId?: string } + const [expanded, setExpanded] = useState(false) // 订单详情是否展开 + const [couponExpanded, setCouponExpanded] = useState(false) // 优惠券详情是否展开 + const [priceExpanded, setPriceExpanded] = useState(false) // 收费标准详情是否展开 + + useLoad(() => { + console.log('订单详情页面加载,订单ID:', orderId) + }) + + // 拨打电话 + const handlePhoneCall = () => { + Taro.makePhoneCall({ + phoneNumber: '100-666-XXXX', + }).catch((err) => { + console.error('拨打电话失败:', err) + }) + } + + // 切换展开/收起 + const handleToggleExpand = () => { + setExpanded(!expanded) + } + + return ( + + {/* 内容区域 */} + + {/* 台球桌信息卡片 */} + + {/* 顶部:类型和店名 */} + + 中式台球 + + + 联系店长 + + + + {/* 台球桌标题和使用状态 */} + + 来力.山岩-A03/3号球桌 + 已完成 + + + {/* 位置信息 */} + + + 北京黑八大师联盟球厅店 + + + + {/* 开台订单信息卡片 */} + + {/* 顶部:开台方式和详情按钮 */} + + + 开台方式 + + + 详情 + + + + + {/* 订单统计 */} + + + 1小时56分 + 已消费时长 + + + 100.00元 + 已消费金额 + + + + {/* 收费规则 */} + + + 收费规则 + + + 价格: + 90.00元/小时 + + + 折扣价: + 80.00元/小时 + + + + + + + {/* 展开的详细信息 */} + {expanded && ( + <> + {/* 支付信息卡片 */} + + 支付信息 + + + 在线总支付: + + 0元 + + + + + 押金 + 0元 + + + + 订单原价 + 92.80元 + + + {/* 优惠券抵扣 - 可展开 */} + setCouponExpanded(!couponExpanded)}> + 优惠券抵扣 + + 不可用 + -96.00元 + + + + + {/* 优惠券展开内容 */} + {couponExpanded && ( + + 美团:2小时通用券(新人奖励) + -96.00元 + + )} + + + 待结算: + 92.8元 + + + + {/* 开台信息卡片 */} + + 开台信息 + + + 门店信息 + XXXXXX店 + + + + 桌台信息 + 中式台球 来力.山岩-A03/3号球桌 + + + + 开始时间 + 2025-01-01 00:00:00 + + + + 使用时长 + 1小时56分 + + + + 订单编号 + 987654321012345678 + + + {/* 收费标准 - 可展开 */} + setPriceExpanded(!priceExpanded)}> + 收费标准 + + 80元/小时 + + + + + {/* 收费标准展开内容 */} + {priceExpanded && ( + + 1分钟以内不计费,超过1分钟按6.67元/5分钟计费 + • 00:00-11:00 原价90元/小时,折扣价80元/小时 + • 11:00-24:00 原价100元/小时,折扣价90元/小时 + + )} + + + 支付方式 + 微信支付 + + + + )} + + + ) +} + +export default OrderDetail diff --git a/src/pagesUser/orderList/components/FilterPopup.scss b/src/pagesUser/orderList/components/FilterPopup.scss new file mode 100644 index 0000000..7705ee7 --- /dev/null +++ b/src/pagesUser/orderList/components/FilterPopup.scss @@ -0,0 +1,179 @@ +.filter-popup { + .filter-container { + background-color: #FFFFFF; + border-top-left-radius: 20px; + border-top-right-radius: 20px; + max-height: 80vh; + display: flex; + flex-direction: column; + + // 标题栏 + .filter-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 33px; + border-bottom: 1px solid #F2F3F5; + + .header-title { + font-size: 32px; + color: #333333; + font-weight: bold; + } + + .close-icon { + cursor: pointer; + } + } + + // 筛选内容 + .filter-content { + flex: 1; + overflow-y: auto; + padding: 0 29px; + + .filter-section { + .section-title { + display: block; + font-size: 29px; + color: #333333; + margin: 33px 0; + } + + // 预制时间段选项 + .period-options { + display: flex; + gap: 20px; + margin-bottom: 30px; + } + + // 支付方式选项 + .payment-options { + display: flex; + gap: 20px; + flex-wrap: wrap; + margin-bottom: 30px; + } + + // 选项按钮样式 + .option-item { + width: 217px; + height: 71px; + background: #F2F3F5; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + .option-text { + font-size: 29px; + color: #333333; + } + + // 选中状态 + &.selected { + background: #3A3D42; + + .option-text { + color: #FFFFFF; + } + } + } + + // 日期范围输入 + .date-range { + display: flex; + align-items: center; + gap: 25px; + margin-bottom: 30px; + + .date-input { + width: 333px; + height: 71px; + background: #FFFFFF; + border-radius: 8px; + border: 1px solid #CCCCCC; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + .date-text { + font-size: 29px; + color: #333333; + } + + .date-placeholder { + font-size: 29px; + color: #999999; + } + + // 有值时的样式 + &.has-value { + border-color: #CCCCCC; + } + } + + .date-separator { + font-size: 29px; + color: #333333; + } + } + } + } + + // 底部按钮 + .filter-footer { + display: flex; + gap: 20px; + padding: 30px; + border-top: 1px solid #F2F3F5; + + .reset-btn { + flex: 1; + height: 88px; + background: #FFFFFF; + border: 2px solid #03C175; + border-radius: 44px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + .reset-text { + font-size: 33px; + color: #03C175; + } + } + + .confirm-btn { + flex: 2; + height: 88px; + background: #03C175; + border-radius: 44px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + .confirm-text { + font-size: 33px; + color: #FFFFFF; + font-weight: bold; + } + } + } + + // 日期选择器 Popup(需要浮在筛选 Popup 上) + .date-picker-popup { + z-index: 10001 !important; + + :global { + .taroify-popup { + z-index: 10000 !important; + } + } + } + } +} diff --git a/src/pagesUser/orderList/components/FilterPopup.tsx b/src/pagesUser/orderList/components/FilterPopup.tsx new file mode 100644 index 0000000..f6d509f --- /dev/null +++ b/src/pagesUser/orderList/components/FilterPopup.tsx @@ -0,0 +1,283 @@ +/** + * 订单筛选弹窗组件 + */ +import { View, Text } from '@tarojs/components' +import { FC, useState } from 'react' +import { Popup, DatetimePicker } from '@taroify/core' +import { Cross } from '@taroify/icons' +import Taro from '@tarojs/taro' +import './FilterPopup.scss' + +interface FilterData { + startDate: string + endDate: string + paymentMethods: string[] // 支付方式(可多选) +} + +interface FilterPopupProps { + open: boolean + onClose: () => void + onConfirm: (data: FilterData) => void +} + +const FilterPopup: FC = ({ open, onClose, onConfirm }) => { + const [selectedPeriod, setSelectedPeriod] = useState('') // 选中的时间段 + const [startDate, setStartDate] = useState('') + const [endDate, setEndDate] = useState('') + const [paymentMethods, setPaymentMethods] = useState([]) + + // 日期选择器相关状态 + const [datePickerOpen, setDatePickerOpen] = useState(false) + const [datePickerType, setDatePickerType] = useState<'start' | 'end'>('start') // 选择开始还是结束时间 + const [pickerValue, setPickerValue] = useState(new Date()) + + // 计算日期 + const calculateDates = (type: '1week' | '1month' | '3months') => { + const today = new Date() + const yesterday = new Date(today) + yesterday.setDate(yesterday.getDate() - 1) + + const startDay = new Date(yesterday) + + if (type === '1week') { + startDay.setDate(startDay.getDate() - 7) + } else if (type === '1month') { + startDay.setMonth(startDay.getMonth() - 1) + } else if (type === '3months') { + startDay.setMonth(startDay.getMonth() - 3) + } + + const formatDate = (date: Date) => { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + return `${year}-${month}-${day}` + } + + return { + start: formatDate(startDay), + end: formatDate(yesterday) + } + } + + // 选择时间段 + const handlePeriodSelect = (type: '1week' | '1month' | '3months') => { + setSelectedPeriod(type) + const dates = calculateDates(type) + setStartDate(dates.start) + setEndDate(dates.end) + } + + // 切换支付方式选择 + const togglePaymentMethod = (method: string) => { + if (paymentMethods.includes(method)) { + setPaymentMethods(paymentMethods.filter(m => m !== method)) + } else { + setPaymentMethods([...paymentMethods, method]) + } + } + + // 打开日期选择器 + const openDatePicker = (type: 'start' | 'end') => { + setDatePickerType(type) + + // 如果已有日期,使用已有日期作为初始值 + if (type === 'start' && startDate) { + setPickerValue(new Date(startDate)) + } else if (type === 'end' && endDate) { + setPickerValue(new Date(endDate)) + } else { + setPickerValue(new Date()) + } + + setDatePickerOpen(true) + } + + // 格式化日期 + const formatDate = (date: Date) => { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + return `${year}-${month}-${day}` + } + + // 日期选择确认 + const handleDateConfirm = (value: Date) => { + const selectedDate = formatDate(value) + + if (datePickerType === 'start') { + // 选择开始时间 + if (endDate && selectedDate > endDate) { + Taro.showToast({ + title: '开始时间不能晚于结束时间', + icon: 'none', + duration: 2000 + }) + setDatePickerOpen(false) + return + } + setStartDate(selectedDate) + } else { + // 选择结束时间 + if (startDate && selectedDate < startDate) { + Taro.showToast({ + title: '结束时间不能早于开始时间', + icon: 'none', + duration: 2000 + }) + setDatePickerOpen(false) + return + } + setEndDate(selectedDate) + } + + // 取消预制时间段的选中状态 + setSelectedPeriod('') + setDatePickerOpen(false) + } + + // 取消日期选择 + const handleDateCancel = () => { + setDatePickerOpen(false) + } + + // 重置 + const handleReset = () => { + setSelectedPeriod('') + setStartDate('') + setEndDate('') + setPaymentMethods([]) + } + + // 确定 + const handleConfirm = () => { + onConfirm({ + startDate, + endDate, + paymentMethods + }) + onClose() + } + + return ( + + + {/* 标题栏 */} + + 订单筛选 + + + + {/* 筛选内容 */} + + {/* 下单时间 */} + + 下单时间 + + {/* 预制时间段选择 */} + + handlePeriodSelect('1week')} + > + 近1周 + + handlePeriodSelect('1month')} + > + 近1个月 + + handlePeriodSelect('3months')} + > + 近3个月 + + + + {/* 日期范围输入 */} + + openDatePicker('start')} + > + + {startDate || '开始时间'} + + + - + openDatePicker('end')} + > + + {endDate || '结束时间'} + + + + + + {/* 支付方式 */} + + 支付方式(可多选) + + + togglePaymentMethod('balance')} + > + 账户余额支付 + + togglePaymentMethod('cash')} + > + 现金支付 + + togglePaymentMethod('coupon')} + > + 团购券支付 + + + + + + {/* 底部按钮 */} + + + 重置 + + + 确定 + + + + {/* 日期选择器 Popup */} + + + + + + ) +} + +export default FilterPopup diff --git a/src/pagesUser/orderList/index.scss b/src/pagesUser/orderList/index.scss index 5486525..31549c7 100644 --- a/src/pagesUser/orderList/index.scss +++ b/src/pagesUser/orderList/index.scss @@ -1,5 +1,184 @@ .order-list-page { min-height: 100vh; background-color: #F2F3F5; - padding: 30px; + + // 第一层 Tab:台球/棋牌 + .category-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: #333333 !important; + } + + // 选中指示线 + .taroify-tabs__line { + background-color: #03C175 !important; + } + } + } + + // 第二层 Tab:全部/进行中/已完成 + .status-tab-container { + display: flex; + align-items: center; + background-color: none; + padding: 0 30px; + position: relative; + + .status-tabs { + flex: 1; + .taroify-tabs__wrap{ + .taroify-tabs__wrap__scroll{ + background: none !important; + + .wx-scroll-view{ + .wx-scroll-view{ + .taroify-tabs__nav{ + background: none !important; + } + } + } + } + } + + :global { + + + // 未选中 Tab + .taroify-tabs__tab { + font-size: 30px !important; + color: #8B8B8B !important; + } + + // 选中 Tab + .taroify-tabs__tab--active { + color: #03C175 !important; + } + + // 选中指示线 + .taroify-tabs__line { + background-color: #03C175 !important; + } + } + } + + // 筛选按钮 + .filter-btn { + display: flex; + align-items: center; + gap: 5px; + padding: 10px 0; + + .filter-text { + font-size: 30px; + color: #8B8B8B; + } + } + } + + // 订单列表 + .order-list { + padding: 30px; + + // 空数据 + .empty-data { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 150px 0; + + .empty-image { + width: 400px; + height: 400px; + margin-bottom: 30px; + } + + .empty-text { + font-size: 30px; + color: #999999; + } + } + + // 订单卡片 + .order-card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 30px; + margin-bottom: 30px; + + // 标题行 + .card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 30px; + + .table-name { + font-size: 33px; + color: #333333; + font-weight: bold; + } + + .status { + font-size: 33px; + + &.ongoing { + color: #03C175; + } + + &.completed { + color: #8B8B8B; + } + } + } + + // 订单信息 + .card-info { + display: flex; + flex-direction: column; + gap: 20px; + + .info-row { + display: flex; + align-items: center; + justify-content: space-between; + + .info-label { + font-size: 30px; + color: #333333; + } + + .info-value { + font-size: 30px; + color: #595959; + } + } + } + } + + // 到底了提示 + .list-end { + text-align: center; + padding: 40px 0; + + .end-text { + font-size: 25px; + color: #999999; + } + } + } } diff --git a/src/pagesUser/orderList/index.tsx b/src/pagesUser/orderList/index.tsx index b34c865..49682b4 100644 --- a/src/pagesUser/orderList/index.tsx +++ b/src/pagesUser/orderList/index.tsx @@ -1,18 +1,201 @@ /** * 订单记录页 */ -import { View, Text } from '@tarojs/components' -import { useLoad } from '@tarojs/taro' +import { View, Text, Image } from '@tarojs/components' +import { useState } from 'react' +import Taro, { useLoad } from '@tarojs/taro' +import { Tabs, Divider } from '@taroify/core' +import { ArrowDown } from '@taroify/icons' +import FilterPopup from './components/FilterPopup' import './index.scss' +const noDataImg = require('../../assets/big/noData.png') + +// 订单数据接口 +interface OrderItem { + id: string + tableName: string // 台球 A02 + storeName: string // 消费门店 + startTime: string // 开台时间 + duration: string // 开台时长 + amount: number // 实付金额 + status: 'ongoing' | 'completed' // 进行中 | 已完成 +} + const OrderList = () => { + const [categoryTab, setCategoryTab] = useState(0) // 0: 台球, 1: 棋牌 + const [statusTab, setStatusTab] = useState(0) // 0: 全部, 1: 进行中, 2: 已完成 + const [filterPopupOpen, setFilterPopupOpen] = useState(false) // 筛选弹窗 + const [filterData, setFilterData] = useState({ + startDate: '', + endDate: '', + paymentMethods: [] as string[] + }) + + // 模拟订单数据 + const [orderList] = useState([ + { + id: '1', + tableName: '台球 A02', + storeName: 'XXXXXXXXXXXX店', + startTime: '2025-01-02 16:30:01', + duration: '1小时30分钟', + amount: 28.80, + status: 'ongoing' + }, + { + id: '2', + tableName: '台球 A01', + storeName: 'XXXXXXXXXXXX店', + startTime: '2025-01-01 16:30:01', + duration: '1小时30分钟', + amount: 28.80, + status: 'completed' + } + ]) + useLoad(() => { console.log('订单记录页面加载') }) + // 筛选按钮点击 + const handleFilter = () => { + setFilterPopupOpen(true) + } + + // 筛选确认 + const handleFilterConfirm = (data: any) => { + setFilterData(data) + + // 计算筛选数量 + let count = 0 + if (data.startDate || data.endDate) count++ + if (data.paymentMethods.length > 0) count += data.paymentMethods.length + + console.log('筛选数据', data, '筛选数量', count) + + Taro.showToast({ + title: '筛选成功', + icon: 'success', + duration: 2000 + }) + } + + // 计算筛选数量 + const getFilterCount = () => { + let count = 0 + if (filterData.startDate || filterData.endDate) count++ + if (filterData.paymentMethods.length > 0) count += filterData.paymentMethods.length + return count + } + + // 根据选中的 Tab 筛选订单 + const getFilteredOrders = () => { + let filtered = orderList + + // 根据状态筛选 + if (statusTab === 1) { + filtered = filtered.filter(order => order.status === 'ongoing') + } else if (statusTab === 2) { + filtered = filtered.filter(order => order.status === 'completed') + } + + return filtered + } + + const filteredOrders = getFilteredOrders() + + // 订单卡片点击 + const handleOrderClick = (orderId: string) => { + console.log('订单详情', orderId) + Taro.navigateTo({ + url: `/pagesUser/orderDetail/index?orderId=${orderId}` + }) + } + return ( - 订单记录 + {/* 第一层 Tab:台球/棋牌 */} + + + + + + + + {/* 第二层 Tab:全部/进行中/已完成 + 筛选 */} + + + + + + + + + 筛选{getFilterCount() > 0 ? ` ${getFilterCount()}` : ''} + + + + + {/* 订单列表 */} + + {filteredOrders.length === 0 ? ( + + + 没有数据哦~ + + ) : ( + <> + {filteredOrders.map(order => ( + handleOrderClick(order.id)} + > + {/* 标题行 */} + + {order.tableName} + + {order.status === 'ongoing' ? '进行中' : '已完成'} + + + + {/* 订单信息 */} + + + 消费门店 + {order.storeName} + + + 开台时间 + {order.startTime} + + + 开台时长 + {order.duration} + + + 实付金额 + {order.amount.toFixed(2)}元 + + + + ))} + + {/* 到底了提示 */} + + 到底了~ + + + )} + + + {/* 筛选弹窗 */} + setFilterPopupOpen(false)} + onConfirm={handleFilterConfirm} + /> ) }