diff --git a/config/index.ts b/config/index.ts index f3502d4..8363125 100644 --- a/config/index.ts +++ b/config/index.ts @@ -1,4 +1,5 @@ import { defineConfig, type UserConfigExport } from '@tarojs/cli' +import path from 'path' // https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数 export default defineConfig<'webpack5'>(async (merge, { command, mode }) => { @@ -25,6 +26,9 @@ export default defineConfig<'webpack5'>(async (merge, { command, mode }) => { }, framework: 'react', compiler: 'webpack5', + alias: { + '@': path.resolve(__dirname, '..', 'src') + }, mini: { miniCssExtractPluginOption: { ignoreOrder: true, diff --git a/src/app.config.ts b/src/app.config.ts index dc81a4f..16abcaa 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -21,6 +21,7 @@ export default defineAppConfig({ name: 'user-package', pages: [ 'poleStorage/index', // 存杆柜记录 + 'cabinetRental/index', // 存杆柜租赁 'orderList/index', // 订单记录 'orderDetail/index', // 订单详情 'unsettledOrders/index', // 未结算账单 diff --git a/src/components/EmptyData/index.scss b/src/components/EmptyData/index.scss new file mode 100644 index 0000000..b4dda8d --- /dev/null +++ b/src/components/EmptyData/index.scss @@ -0,0 +1,31 @@ +.empty-data-component { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 150px 0; + + .empty-image { + margin-bottom: 30px; + + &.small { + width: 200px; + height: 200px; + } + + &.medium { + width: 300px; + height: 300px; + } + + &.large { + width: 400px; + height: 400px; + } + } + + .empty-text { + font-size: 30px; + color: #999999; + } +} diff --git a/src/components/EmptyData/index.tsx b/src/components/EmptyData/index.tsx new file mode 100644 index 0000000..302ffa3 --- /dev/null +++ b/src/components/EmptyData/index.tsx @@ -0,0 +1,30 @@ +/** + * 空数据组件 + */ +import { View, Text, Image } from '@tarojs/components' +import './index.scss' + +const noDataImg = require('../../assets/big/noData.png') + +interface EmptyDataProps { + text?: string + imageSize?: 'small' | 'medium' | 'large' +} + +const EmptyData: React.FC = ({ + text = '没有数据哦~', + imageSize = 'medium' +}) => { + return ( + + + {text} + + ) +} + +export default EmptyData diff --git a/src/pages/scan/index.tsx b/src/pages/scan/index.tsx index 1e730b5..923e7e2 100644 --- a/src/pages/scan/index.tsx +++ b/src/pages/scan/index.tsx @@ -65,6 +65,13 @@ const ScanIndex = observer(() => { }) } + // 去存杆柜 + const handlePoleStorage = () => { + Taro.navigateTo({ + url: '/pagesUser/poleStorage/index' + }) + } + return ( @@ -86,6 +93,9 @@ const ScanIndex = observer(() => { + {/* 未结算订单提示弹窗 */} diff --git a/src/pagesOrder/images/pipeIcon.png b/src/pagesOrder/images/pipeIcon.png new file mode 100644 index 0000000..38d1f4d Binary files /dev/null and b/src/pagesOrder/images/pipeIcon.png differ diff --git a/src/pagesUser/cabinetRental/index.config.ts b/src/pagesUser/cabinetRental/index.config.ts new file mode 100644 index 0000000..91b4677 --- /dev/null +++ b/src/pagesUser/cabinetRental/index.config.ts @@ -0,0 +1,5 @@ +export default { + navigationBarTitleText: '存杆柜', + navigationBarBackgroundColor: '#FFFFFF', + navigationBarTextStyle: 'black', +} diff --git a/src/pagesUser/cabinetRental/index.scss b/src/pagesUser/cabinetRental/index.scss new file mode 100644 index 0000000..8f863c8 --- /dev/null +++ b/src/pagesUser/cabinetRental/index.scss @@ -0,0 +1,239 @@ +.cabinet-rental-page { + min-height: 100vh; + background-color: #F2F3F5; + padding-bottom: calc(120px + env(safe-area-inset-bottom)); // 为底部按钮留空间 + + // 内容区域 + .content-area { + padding: 30px; + + // 上部分:店铺信息 + .store-info { + margin-bottom: 30px; + + .store-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 20px; + + .store-title { + font-size: 33px; + color: #333333; + font-weight: 500; + } + + .contact-btn { + width: 168px; + height: 60px; + background: #03C175; + border-radius: 30px; + border: none; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + margin: 0; + + .contact-text { + font-size: 28px; + color: #FFFFFF; + } + } + } + + .store-address { + font-size: 25px; + color: #595959; + line-height: 1.6; + } + } + + // 中间部分:计费计算区域 + .rental-card { + background-color: #FFFFFF; + border-radius: 12px; + padding: 34px 30px; + margin-bottom: 30px; + + // 柜子名称和标签 + .cabinet-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 30px; + + .cabinet-name { + font-size: 35px; + color: #1A1A1A; + font-weight: 500; + } + + .cabinet-tag { + background: #03C175; + border-radius: 8px; + padding: 8px 20px; + + .tag-text { + font-size: 25px; + color: #FFFFFF; + } + + &.return-tag { + background: #FF9500; + } + } + } + + // 分割线 + .divider { + height: 1px; + background-color: #E8E8E8; + margin: 30px 0; + } + + // 信息行(租金、押金) + .info-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 30px; + + .info-label { + font-size: 31px; + color: #000000; + } + + .info-value { + font-size: 31px; + color: #000000; + + &.status-using { + color: #03C175; + } + } + } + + // 预付租金 + .deposit-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 30px; + + .deposit-label { + font-size: 31px; + color: #000000; + } + + .deposit-stepper { + // 输入框相关 + --stepper-input-width: 100px; + --stepper-input-height: 56px; + --stepper-input-font-size: 31px; + --stepper-input-color: #000000; + --stepper-input-background-color: #FFFFFF; + + // 圆形风格 - 减号按钮 + --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; + } + } + + // 支付方式 + .payment-row { + display: flex; + align-items: center; + justify-content: space-between; + + .payment-label { + font-size: 31px; + color: #000000; + } + + .payment-value { + font-size: 31px; + color: #000000; + } + } + } + + // 下部分:温馨提示 + .tips-section { + display: flex; + flex-direction: column; + gap: 10px; + + .tips-title { + font-size: 25px; + color: #666666; + margin-bottom: 5px; + } + + .tips-text { + font-size: 25px; + color: #666666; + line-height: 1.6; + } + } + } + + // 底部固定区域 + .footer-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 30px; + padding-bottom: calc(20px + env(safe-area-inset-bottom)); + background-color: #FFFFFF; + box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.1); + + .payment-info { + display: flex; + align-items: baseline; + + .payment-label { + font-size: 28px; + color: #000000; + margin-right: 8px; + } + + .payment-symbol { + font-size: 28px; + color: #000000; + } + + .payment-amount { + font-size: 45px; + color: #000000; + font-weight: 500; + } + } + + .confirm-btn { + width: 200px; + height: 88px; + background-color: #01CA68; + border-radius: 44px; + display: flex; + align-items: center; + justify-content: center; + + .confirm-text { + font-size: 33px; + color: #FFFFFF; + font-weight: 500; + } + } + } +} diff --git a/src/pagesUser/cabinetRental/index.tsx b/src/pagesUser/cabinetRental/index.tsx new file mode 100644 index 0000000..323ee4e --- /dev/null +++ b/src/pagesUser/cabinetRental/index.tsx @@ -0,0 +1,254 @@ +/** + * 存杆柜租赁页面 + */ +import { View, Text, Button } from '@tarojs/components' +import Taro, { useLoad } from '@tarojs/taro' +import { useState } from 'react' +import { Stepper } from '@taroify/core' +import './index.scss' +import { Arrow } from '@taroify/icons' + +const phoneIcon = require('../../pageScan/startTable/images/phone.png') + +const CabinetRental = () => { + const [depositAmount, setDepositAmount] = useState(1000) // 预付租金 + const [paymentMethod] = useState('微信支付') // 支付方式 + + // 页面参数 + const [cabinetName, setCabinetName] = useState('A01号柜') // 柜子名称 + const [cabinetId, setCabinetId] = useState('') // 柜子ID + const [pageType, setPageType] = useState<'rental' | 'renew' | 'return'>('rental') // 页面类型:rental-租赁, renew-续租, return-退租 + + useLoad(() => { + console.log('存杆柜租赁页面加载') + + // 获取页面参数 + const router = Taro.getCurrentInstance().router + if (router?.params) { + const { cabinetName: name, cabinetId: id, type } = router.params + if (name) setCabinetName(decodeURIComponent(name)) + if (id) setCabinetId(id) + if (type) setPageType(type as 'rental' | 'renew' | 'return') + } + }) + + // 拨打电话 + const handlePhoneCall = () => { + Taro.makePhoneCall({ + phoneNumber: '100-666-XXXX', + }).catch((err) => { + console.error('拨打电话失败:', err) + }) + } + + // 预付租金变化 + const handleDepositChange = (value: number) => { + setDepositAmount(value) + } + + // 选择支付方式 + const handleSelectPayment = () => { + Taro.showToast({ + title: '暂时只支持微信支付', + icon: 'none', + duration: 2000 + }) + } + + // 立即租赁/续租/退租 + const handleConfirm = () => { + let action = '租赁' + if (pageType === 'renew') action = '续租' + if (pageType === 'return') action = '退租' + + console.log(`立即${action}`, { + cabinetId, + cabinetName, + totalAmount: getTotalAmount(), + type: pageType + }) + Taro.showToast({ + title: `${action}成功`, + icon: 'success', + duration: 2000 + }) + } + + // 计算总金额 + const getTotalAmount = () => { + if (pageType === 'return') { + // 退租:应退金额 = 押金 + 预付租金 - 已消费 + const deposit = 100 // 押金 + const prepaid = 30 // 预付租金 + const consumed = 20 // 已消费 + return deposit + prepaid - consumed // 110元 + } + // 租赁/续租:租金1元 + 押金100元 + 预付租金 + return 1 + 100 + depositAmount + } + + // 获取按钮文案 + const getButtonText = () => { + if (pageType === 'rental') return '立即租赁' + if (pageType === 'renew') return '立即续租' + return '立即退租' + } + + // 获取标签文案 + const getTagText = () => { + if (pageType === 'rental') return '租赁' + if (pageType === 'renew') return '续租' + return '退租' + } + + return ( + + {/* 内容区域 */} + + {/* 上部分:店铺信息 */} + + + 北京黑八大师联盟球厅店 + + 联系店长 + + + + 北京市XXX区XXX街道XXXXXXXXXXXX路卖场XXXXXXXXXX大厦101 + + + + {/* 中间部分:计费计算区域 */} + + {/* 柜子名称和标签 */} + + {cabinetName} + + {getTagText()} + + + + {/* 分割线 */} + + + {/* 根据类型显示不同内容 */} + {pageType === 'return' ? ( + <> + {/* 退租信息 */} + + 状态 + 使用中 + + + 租赁开始时间 + 2025-01-01 + + + 租赁截止时间 + 2025-01-30 + + + 已使用时间 + 20天 + + + 剩余时间 + 10天 + + + 押金 + 100.00元 + + + 预付租金 + 30.00元 + + + 已消费 + 20.00元 + + + 应退金额 + 110.00元 + + + 用户编号 + id123456 + + + ) : ( + <> + {/* 租赁/续租信息 */} + + 租金 + 1元/天 + + + 押金 + 100元 + + + 预付租金(元) + + + + )} + + {pageType !== 'return' && ( + {/* 支付方式 / 用户编号 */} + + + 支付方式 + + {paymentMethod} + + + + + )} + + {/* 下部分:温馨提示 */} + + 温馨提示: + {pageType === 'return' ? ( + <> + 1. 请仔细检查柜内是否有私人物品遗留。 + 2. 使用完毕请关闭柜门,否则将不返还押金。 + 3. 应退金额将在柜子退租关闭后48小时内返回。 + + ) : ( + <> + 1. 使用完毕请关闭柜门,防止贵重物品丢失。 + + 2. 租赁:支付费用后,有效期间可随时使用,租赁后请留意截止日期,过期需补足租赁费用。 + + 3. 仅支持存放球杆等。 + + )} + + + + {/* 底部固定区域 */} + + + {pageType === 'return' ? '应退金额' : '需支付'} + + {getTotalAmount().toFixed(2)} + + + {getButtonText()} + + + + ) +} + +export default CabinetRental diff --git a/src/pagesUser/poleStorage/index.config.ts b/src/pagesUser/poleStorage/index.config.ts index 3410d0e..91b4677 100644 --- a/src/pagesUser/poleStorage/index.config.ts +++ b/src/pagesUser/poleStorage/index.config.ts @@ -1,5 +1,5 @@ export default { - navigationBarTitleText: '存杆柜记录', + navigationBarTitleText: '存杆柜', navigationBarBackgroundColor: '#FFFFFF', navigationBarTextStyle: 'black', } diff --git a/src/pagesUser/poleStorage/index.scss b/src/pagesUser/poleStorage/index.scss index cf5387b..3129073 100644 --- a/src/pagesUser/poleStorage/index.scss +++ b/src/pagesUser/poleStorage/index.scss @@ -1,5 +1,256 @@ .pole-storage-page { min-height: 100vh; background-color: #F2F3F5; - padding: 30px; + + // 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: #333333 !important; + } + + // 选中指示线 + .taroify-tabs__line { + background-color: #03C175 !important; + } + } + } + + // 内容区域 + .content-area { + padding: 30px; + } + + // 柜子列表 + .cabinet-list { + // 卡片基础样式 + .cabinet-card { + background-color: #FFFFFF; + border-radius: 12px; + margin-bottom: 29px; + + &:last-child { + margin-bottom: 0; + } + } + + // 我的柜子卡片 + .mine-card { + padding: 30px; + + // 上部分 + .card-top { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 30px; + + // 左侧:图标和柜子名称 + .left-info { + display: flex; + align-items: center; + gap: 20px; + + .cabinet-icon { + width: 37px; + height: 41px; + flex-shrink: 0; + } + + .cabinet-name { + font-size: 35px; + color: #1A1A1A; + font-weight: 500; + } + } + + // 右侧:日期和剩余天数 + .right-info { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 10px; + + .date-info { + display: flex; + align-items: center; + line-height: 1; + + .date-text { + font-size: 25px; + color: #595959; + } + + .date-separator { + font-size: 25px; + color: #8B8B8B; + } + } + + .remain-info { + display: flex; + align-items: center; + line-height: 1; + + .remain-text { + font-size: 25px; + color: #595959; + } + + .remain-days { + font-size: 25px; + color: #03C175; + font-weight: 500; + } + } + } + } + + // 分割线 + .divider { + height: 1PX; + // background-color: #D3D8DE; + margin-bottom: 30px; + border: 1px dashed #D3D8DE; + } + + // 下部分 - 按钮组 + .card-bottom { + display: flex; + gap: 20px; + + .action-btn { + flex: 1; + height: 66px; + border-radius: 33px; + font-size: 30px; + font-weight: 400; + border: none; + display: flex; + align-items: center; + justify-content: center; + } + + // 开门按钮 + .open-btn { + background: #0C84FE; + color: #FFFFFF; + } + + // 续租按钮 + .renew-btn { + background: #FF9500; + color: #FFFFFF; + } + + // 退租按钮 + .return-btn { + background: transparent; + color: #FF9500; + border: 1PX solid #FF9500; + } + } + } + + // 可租赁卡片 + .available-card { + padding: 26px 30px; + + .available-content { + display: flex; + align-items: center; + justify-content: space-between; + + .left-content { + display: flex; + align-items: center; + gap: 20px; + + .cabinet-icon-small { + width: 37px; + height: 41px; + } + + .cabinet-name-small { + font-size: 35px; + color: #1A1A1A; + font-weight: 500; + } + } + + .rent-btn { + width: 160px; + height: 66px; + background: #03C175; + border-radius: 33px; + color: #FFFFFF; + font-size: 30px; + font-weight: 400; + border: none; + display: flex; + align-items: center; + justify-content: center; + margin:0; + } + } + } + + // 使用中卡片 + .inuse-card { + padding: 26px 30px; + + .inuse-content { + display: flex; + align-items: center; + justify-content: space-between; + + .left-content { + display: flex; + align-items: center; + gap: 20px; + + .cabinet-icon-small { + width: 37px; + height: 41px; + } + + .cabinet-name-small { + font-size: 35px; + color: #1A1A1A; + font-weight: 500; + } + } + + .status-badge { + width: 160px; + height: 66px; + background: #E8E8E8; + border-radius: 33px; + display: flex; + align-items: center; + justify-content: center; + + .status-text { + font-size: 30px; + color: #8B8B8B; + font-weight: 400; + } + } + } + } + } } diff --git a/src/pagesUser/poleStorage/index.tsx b/src/pagesUser/poleStorage/index.tsx index 63ef758..90d40e6 100644 --- a/src/pagesUser/poleStorage/index.tsx +++ b/src/pagesUser/poleStorage/index.tsx @@ -1,18 +1,204 @@ /** - * 存杆柜记录页 + * 存杆柜租赁页 */ -import { View, Text } from '@tarojs/components' -import { useLoad } from '@tarojs/taro' +import { View, Text, Image, Button } from '@tarojs/components' +import { useState } from 'react' +import Taro, { useLoad } from '@tarojs/taro' +import { Tabs } from '@taroify/core' +import EmptyData from '@/components/EmptyData' import './index.scss' +const pipeIcon = require('../../pagesOrder/images/pipeIcon.png') + +// 存杆柜数据接口 +interface CabinetItem { + id: string + name: string // A03号柜 + startDate?: string // 开始日期(已租赁才有) + endDate?: string // 结束日期(已租赁才有) + remainDays?: number // 剩余天数(已租赁才有) + status: 'mine' | 'available' | 'inUse' // 我的 | 可租赁 | 使用中 +} + const PoleStorage = () => { + const [activeTab, setActiveTab] = useState(0) // 0: 我的, 1: 可租赁, 2: 使用中 + + // 模拟数据 + const [myCabinets] = useState([ + { + id: '1', + name: 'A03号柜', + startDate: '2025-01-01', + endDate: '2025-01-10', + remainDays: 9, + status: 'mine' + } + ]) + + const [availableCabinets] = useState([ + { + id: '2', + name: 'A01号柜', + status: 'available' + }, + { + id: '3', + name: 'A02号柜', + status: 'available' + } + ]) + + const [inUseCabinets] = useState([ + { + id: '4', + name: 'A04号柜', + status: 'inUse' + } + ]) + useLoad(() => { - console.log('存杆柜记录页面加载') + console.log('存杆柜租赁页面加载') }) + // 开门 + const handleOpenDoor = (id: string) => { + console.log('开门', id) + Taro.showToast({ + title: '开门成功', + icon: 'success' + }) + } + + // 续租 + const handleRenew = (id: string, cabinetName: string) => { + console.log('续租', id, cabinetName) + Taro.navigateTo({ + url: `/pagesUser/cabinetRental/index?cabinetId=${id}&cabinetName=${cabinetName}&type=renew` + }) + } + + // 退租 + const handleReturn = (id: string, cabinetName: string) => { + console.log('退租', id, cabinetName) + Taro.navigateTo({ + url: `/pagesUser/cabinetRental/index?cabinetId=${id}&cabinetName=${cabinetName}&type=return` + }) + } + + // 租赁 + const handleRent = (id: string, cabinetName: string) => { + console.log('租赁', id, cabinetName) + Taro.navigateTo({ + url: `/pagesUser/cabinetRental/index?cabinetId=${id}&cabinetName=${cabinetName}&type=rental` + }) + } + + // 渲染我的柜子卡片 + const renderMineCard = (cabinet: CabinetItem) => ( + + {/* 上部分 */} + + {/* 左侧:图标和柜子名称 */} + + + {cabinet.name} + + + {/* 右侧:日期和剩余天数 */} + + + {cabinet.startDate} + + {cabinet.endDate} + + + 剩余 + {cabinet.remainDays} + + + + + + {/* 分割线 */} + + + {/* 下部分 - 按钮组 */} + + + + + + + ) + + // 渲染可租赁卡片 + const renderAvailableCard = (cabinet: CabinetItem) => ( + + + + + {cabinet.name} + + + + + ) + + // 渲染使用中卡片 + const renderInUseCard = (cabinet: CabinetItem) => ( + + + + + {cabinet.name} + + + 使用中 + + + + ) + + // 根据当前 Tab 获取数据 + const getCurrentData = () => { + if (activeTab === 0) return myCabinets + if (activeTab === 1) return availableCabinets + return inUseCabinets + } + + const currentData = getCurrentData() + return ( - 存杆柜记录 + {/* Tab 导航 */} + + + + + + + + + {/* 内容区域 */} + + {currentData.length === 0 ? ( + + ) : ( + + {activeTab === 0 && myCabinets.map(cabinet => renderMineCard(cabinet))} + {activeTab === 1 && availableCabinets.map(cabinet => renderAvailableCard(cabinet))} + {activeTab === 2 && inUseCabinets.map(cabinet => renderInUseCard(cabinet))} + + )} + ) } diff --git a/src/pagesUser/unsettledOrders/index.scss b/src/pagesUser/unsettledOrders/index.scss index 84506b0..9f970d0 100644 --- a/src/pagesUser/unsettledOrders/index.scss +++ b/src/pagesUser/unsettledOrders/index.scss @@ -3,26 +3,6 @@ background-color: #F2F3F5; padding: 30px; - // 空数据 - .empty-data { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 150px 0; - - .empty-image { - width: 300px; - height: 300px; - margin-bottom: 30px; - } - - .empty-text { - font-size: 30px; - color: #999999; - } - } - // 订单列表 .order-list { // 订单卡片 diff --git a/src/pagesUser/unsettledOrders/index.tsx b/src/pagesUser/unsettledOrders/index.tsx index fac65e7..ea30778 100644 --- a/src/pagesUser/unsettledOrders/index.tsx +++ b/src/pagesUser/unsettledOrders/index.tsx @@ -1,15 +1,14 @@ /** * 未结算账单页 */ -import { View, Text, Image, Button } from '@tarojs/components' +import { View, Text, Button } from '@tarojs/components' import { useState } from 'react' import Taro, { useLoad } from '@tarojs/taro' import { Divider } from '@taroify/core' import { Arrow } from '@taroify/icons' +import EmptyData from '@/components/EmptyData' import './index.scss' -const noDataImg = require('../../assets/big/noData.png') - // 未结算订单数据接口 interface UnsettledOrderItem { id: string @@ -49,10 +48,7 @@ const UnsettledOrders = () => { return ( {orderList.length === 0 ? ( - - - 没有数据哦~ - + ) : ( {orderList.map(order => (