|
@@ -1,5 +1,5 @@
|
|
|
import { View, Text, ScrollView } from '@tarojs/components'
|
|
import { View, Text, ScrollView } from '@tarojs/components'
|
|
|
-import Taro, { useRouter, navigateTo, showToast } from '@tarojs/taro'
|
|
|
|
|
|
|
+import Taro, { useRouter, navigateTo } from '@tarojs/taro'
|
|
|
import { useState, useEffect } from 'react'
|
|
import { useState, useEffect } from 'react'
|
|
|
import { useQuery, useMutation } from '@tanstack/react-query'
|
|
import { useQuery, useMutation } from '@tanstack/react-query'
|
|
|
import { orderClient, paymentClient, routeClient, passengerClient } from '@/api'
|
|
import { orderClient, paymentClient, routeClient, passengerClient } from '@/api'
|
|
@@ -139,14 +139,14 @@ export default function OrderPage() {
|
|
|
// TODO: 实际项目中需要发送code到后端获取手机号
|
|
// TODO: 实际项目中需要发送code到后端获取手机号
|
|
|
setPhoneNumber('138****8888')
|
|
setPhoneNumber('138****8888')
|
|
|
setHasPhoneNumber(true)
|
|
setHasPhoneNumber(true)
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '手机号获取成功',
|
|
title: '手机号获取成功',
|
|
|
icon: 'success',
|
|
icon: 'success',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
|
})
|
|
})
|
|
|
} else {
|
|
} else {
|
|
|
console.error('获取手机号失败:', e.detail.errMsg)
|
|
console.error('获取手机号失败:', e.detail.errMsg)
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '获取手机号失败,请重试',
|
|
title: '获取手机号失败,请重试',
|
|
|
icon: 'error',
|
|
icon: 'error',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -157,7 +157,7 @@ export default function OrderPage() {
|
|
|
// 添加乘客
|
|
// 添加乘客
|
|
|
const handleAddPassenger = () => {
|
|
const handleAddPassenger = () => {
|
|
|
if (!hasPhoneNumber) {
|
|
if (!hasPhoneNumber) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '请先获取手机号',
|
|
title: '请先获取手机号',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -179,7 +179,7 @@ export default function OrderPage() {
|
|
|
// 检查是否已经添加过这个乘车人
|
|
// 检查是否已经添加过这个乘车人
|
|
|
const existingPassenger = passengers.find(p => p.idNumber === passenger.idNumber)
|
|
const existingPassenger = passengers.find(p => p.idNumber === passenger.idNumber)
|
|
|
if (existingPassenger) {
|
|
if (existingPassenger) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '该乘车人已添加',
|
|
title: '该乘车人已添加',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -327,7 +327,7 @@ export default function OrderPage() {
|
|
|
// 创建订单并支付
|
|
// 创建订单并支付
|
|
|
const handlePay = async () => {
|
|
const handlePay = async () => {
|
|
|
if (!hasPhoneNumber) {
|
|
if (!hasPhoneNumber) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '请先获取手机号',
|
|
title: '请先获取手机号',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -336,7 +336,7 @@ export default function OrderPage() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (passengers.length === 0) {
|
|
if (passengers.length === 0) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '请至少添加一个乘车人',
|
|
title: '请至少添加一个乘车人',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -345,7 +345,7 @@ export default function OrderPage() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!schedule) {
|
|
if (!schedule) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '路线数据加载中,请稍后',
|
|
title: '路线数据加载中,请稍后',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -355,7 +355,7 @@ export default function OrderPage() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!isCharter && passengers.length > (schedule.availableSeats || 0)) {
|
|
if (!isCharter && passengers.length > (schedule.availableSeats || 0)) {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: `座位不足,最多可购买${schedule.availableSeats}张票`,
|
|
title: `座位不足,最多可购买${schedule.availableSeats}张票`,
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -396,7 +396,7 @@ export default function OrderPage() {
|
|
|
|
|
|
|
|
if (wechatPaymentResult.success) {
|
|
if (wechatPaymentResult.success) {
|
|
|
// 支付成功,跳转到支付成功页面
|
|
// 支付成功,跳转到支付成功页面
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '支付成功',
|
|
title: '支付成功',
|
|
|
icon: 'success',
|
|
icon: 'success',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -408,13 +408,13 @@ export default function OrderPage() {
|
|
|
} else {
|
|
} else {
|
|
|
// 支付失败处理
|
|
// 支付失败处理
|
|
|
if (wechatPaymentResult.type === 'cancel') {
|
|
if (wechatPaymentResult.type === 'cancel') {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '支付已取消',
|
|
title: '支付已取消',
|
|
|
icon: 'none',
|
|
icon: 'none',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
|
})
|
|
})
|
|
|
} else {
|
|
} else {
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: wechatPaymentResult.message || '支付失败,请重试',
|
|
title: wechatPaymentResult.message || '支付失败,请重试',
|
|
|
icon: 'error',
|
|
icon: 'error',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -427,7 +427,7 @@ export default function OrderPage() {
|
|
|
|
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('支付失败:', error)
|
|
console.error('支付失败:', error)
|
|
|
- showToast({
|
|
|
|
|
|
|
+ Taro.showToast({
|
|
|
title: '支付失败,请重试',
|
|
title: '支付失败,请重试',
|
|
|
icon: 'error',
|
|
icon: 'error',
|
|
|
duration: 2000
|
|
duration: 2000
|
|
@@ -453,12 +453,13 @@ export default function OrderPage() {
|
|
|
leftIcon="i-heroicons-arrow-left-20-solid"
|
|
leftIcon="i-heroicons-arrow-left-20-solid"
|
|
|
onClickLeft={() => Taro.navigateBack()}
|
|
onClickLeft={() => Taro.navigateBack()}
|
|
|
{...NavbarPresets.primary}
|
|
{...NavbarPresets.primary}
|
|
|
|
|
+ data-testid="order-navbar"
|
|
|
/>
|
|
/>
|
|
|
|
|
|
|
|
<ScrollView className="flex-1 pb-24">
|
|
<ScrollView className="flex-1 pb-24">
|
|
|
{/* 活动信息 */}
|
|
{/* 活动信息 */}
|
|
|
<View className="bg-gradient-to-r from-primary to-primary-dark px-4 py-8 text-white shadow-lg">
|
|
<View className="bg-gradient-to-r from-primary to-primary-dark px-4 py-8 text-white shadow-lg">
|
|
|
- <Text className="text-2xl font-bold text-center tracking-wide">{decodedActivityName || '活动'}</Text>
|
|
|
|
|
|
|
+ <Text className="text-2xl font-bold text-center tracking-wide" data-testid="activity-name">{decodedActivityName || '活动'}</Text>
|
|
|
</View>
|
|
</View>
|
|
|
|
|
|
|
|
{/* 班次信息 */}
|
|
{/* 班次信息 */}
|
|
@@ -466,7 +467,7 @@ export default function OrderPage() {
|
|
|
<Card className={`${isCharter ? 'bg-gradient-to-br from-charter-dark to-charter-bg border-2 border-charter shadow-charter' : 'bg-white/95 shadow-lg backdrop-blur-md border border-white/40'} rounded-2xl`}>
|
|
<Card className={`${isCharter ? 'bg-gradient-to-br from-charter-dark to-charter-bg border-2 border-charter shadow-charter' : 'bg-white/95 shadow-lg backdrop-blur-md border border-white/40'} rounded-2xl`}>
|
|
|
<CardContent className="p-6">
|
|
<CardContent className="p-6">
|
|
|
<View className="flex justify-between items-center mb-6 pb-4 border-b border-gray-200">
|
|
<View className="flex justify-between items-center mb-6 pb-4 border-b border-gray-200">
|
|
|
- <Text className={`text-xl font-bold tracking-wide ${isCharter ? 'text-charter' : 'text-gray-900'}`}>
|
|
|
|
|
|
|
+ <Text className={`text-xl font-bold tracking-wide ${isCharter ? 'text-charter' : 'text-gray-900'}`} data-testid="service-type">
|
|
|
{isCharter ? '包车服务' : '班次信息'}
|
|
{isCharter ? '包车服务' : '班次信息'}
|
|
|
</Text>
|
|
</Text>
|
|
|
<View className="bg-primary text-white px-4 py-2 rounded-full text-xs font-semibold tracking-wide">
|
|
<View className="bg-primary text-white px-4 py-2 rounded-full text-xs font-semibold tracking-wide">
|
|
@@ -495,7 +496,7 @@ export default function OrderPage() {
|
|
|
<Text className={`text-sm font-medium ${isCharter ? 'text-gray-300' : 'text-gray-600'}`}>
|
|
<Text className={`text-sm font-medium ${isCharter ? 'text-gray-300' : 'text-gray-600'}`}>
|
|
|
{isCharter ? '包车价格' : '单人票价'}
|
|
{isCharter ? '包车价格' : '单人票价'}
|
|
|
</Text>
|
|
</Text>
|
|
|
- <Text className={`text-base font-bold ${isCharter ? 'text-charter' : 'text-primary'}`}>
|
|
|
|
|
|
|
+ <Text className={`text-base font-bold ${isCharter ? 'text-charter' : 'text-primary'}`} data-testid="price-per-unit">
|
|
|
¥{schedule.price}{isCharter ? '/车' : '/人'}
|
|
¥{schedule.price}{isCharter ? '/车' : '/人'}
|
|
|
</Text>
|
|
</Text>
|
|
|
</View>
|
|
</View>
|
|
@@ -535,6 +536,7 @@ export default function OrderPage() {
|
|
|
openType="getPhoneNumber"
|
|
openType="getPhoneNumber"
|
|
|
onGetPhoneNumber={handleGetPhoneNumber}
|
|
onGetPhoneNumber={handleGetPhoneNumber}
|
|
|
className="w-full"
|
|
className="w-full"
|
|
|
|
|
+ data-testid="get-phone-button"
|
|
|
>
|
|
>
|
|
|
<View className="flex items-center justify-center">
|
|
<View className="flex items-center justify-center">
|
|
|
<View className="i-heroicons-phone-20-solid w-5 h-5 mr-2" />
|
|
<View className="i-heroicons-phone-20-solid w-5 h-5 mr-2" />
|
|
@@ -595,6 +597,7 @@ export default function OrderPage() {
|
|
|
size="lg"
|
|
size="lg"
|
|
|
onClick={handleAddPassenger}
|
|
onClick={handleAddPassenger}
|
|
|
className="w-full"
|
|
className="w-full"
|
|
|
|
|
+ data-testid="add-passenger-button"
|
|
|
>
|
|
>
|
|
|
<View className="flex items-center justify-center">
|
|
<View className="flex items-center justify-center">
|
|
|
<View className="i-heroicons-plus-20-solid w-5 h-5 mr-2" />
|
|
<View className="i-heroicons-plus-20-solid w-5 h-5 mr-2" />
|
|
@@ -636,7 +639,7 @@ export default function OrderPage() {
|
|
|
|
|
|
|
|
<View className="flex justify-between items-center pt-6 border-t border-gray-200">
|
|
<View className="flex justify-between items-center pt-6 border-t border-gray-200">
|
|
|
<Text className={`text-xl font-bold tracking-wide ${isCharter ? 'text-charter' : 'text-gray-900'}`}>实付金额</Text>
|
|
<Text className={`text-xl font-bold tracking-wide ${isCharter ? 'text-charter' : 'text-gray-900'}`}>实付金额</Text>
|
|
|
- <Text className={`text-3xl font-bold ${isCharter ? 'text-charter' : 'text-primary'}`}>¥{totalPrice}</Text>
|
|
|
|
|
|
|
+ <Text className={`text-3xl font-bold ${isCharter ? 'text-charter' : 'text-primary'}`} data-testid="total-price">¥{totalPrice}</Text>
|
|
|
</View>
|
|
</View>
|
|
|
</CardContent>
|
|
</CardContent>
|
|
|
</Card>
|
|
</Card>
|
|
@@ -652,6 +655,7 @@ export default function OrderPage() {
|
|
|
onClick={handlePay}
|
|
onClick={handlePay}
|
|
|
disabled={createOrderMutation.isPending || createPaymentMutation.isPending}
|
|
disabled={createOrderMutation.isPending || createPaymentMutation.isPending}
|
|
|
className="w-full shadow-lg"
|
|
className="w-full shadow-lg"
|
|
|
|
|
+ data-testid="pay-button"
|
|
|
>
|
|
>
|
|
|
{createOrderMutation.isPending || createPaymentMutation.isPending ? (
|
|
{createOrderMutation.isPending || createPaymentMutation.isPending ? (
|
|
|
<View className="flex items-center justify-center">
|
|
<View className="flex items-center justify-center">
|