feat(share-trip): 新增行程分享页面的UI与状态管理
| | |
| | | position: relative; |
| | | } |
| | | |
| | | .share-trip-expired { |
| | | width: 100vw; |
| | | height: 100vh; |
| | | background: #ffffff; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .expired-content { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | padding-top: 408px; |
| | | |
| | | .expired-img { |
| | | width: 254px; |
| | | height: 254px; |
| | | margin-bottom: 18px; |
| | | } |
| | | |
| | | .expired-text { |
| | | font-size: 30px; |
| | | line-height: 46px; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | |
| | | .expired-sub-text { |
| | | font-size: 30px; |
| | | line-height: 46px; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | |
| | | .expired-btn { |
| | | width: 264px; |
| | | height: 96px; |
| | | /* 自动布局 */ |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | border-radius: 16px; |
| | | box-sizing: border-box; |
| | | /* 按钮色/面性线性按钮 */ |
| | | border: 2px solid #181916; |
| | | padding: 25px 0px; |
| | | font-size: 30px; |
| | | line-height: 46px; |
| | | color: #181916; |
| | | margin-top: 74px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .select-city { |
| | | position: fixed; |
| | | top: 96px; |
| | |
| | | |
| | | &-inner { |
| | | position: relative; |
| | | } |
| | | } |
| | | |
| | | .share-contact { |
| | | position: absolute; |
| | | bottom: calc(100% + 28px); |
| | | right: 24px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 72px; |
| | | height: 72px; |
| | | border-radius: 16px; |
| | | background: #ffffff; |
| | | box-shadow: 0px 4px 16px 0px rgba(84, 92, 143, 0.1); |
| | | z-index: 11; |
| | | transition: bottom 0.3s ease; /* 可选,平滑过渡效果 */ |
| | | |
| | | &.has-tip { |
| | | bottom: calc(100% + 74px + 28px); /* tip-box 向上偏移了 74px */ |
| | | } |
| | | |
| | | .share-contact-icon { |
| | | /* 自动布局子元素 */ |
| | | width: 64px; |
| | | height: 64px; |
| | | z-index: 0; |
| | | } |
| | | } |
| | | |
| | | .car-time { |
| | | display: flex; |
| | | align-items: flex-end; |
| | | justify-content: center; |
| | | font-size: 24px; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | .car-time-num { |
| | | font-size: 36px; |
| | | line-height: 40px; |
| | | color: #6d7fd9; |
| | | } |
| | | |
| | | .car-time-tip { |
| | | margin-left: 6px; |
| | | font-size: 24px; |
| | | line-height: 34px; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | .calling-car-head { |
| | | position: relative; |
| | | z-index: 9; |
| | | font-size: 32px; |
| | | font-weight: 500; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | .calling-car-head-title { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .calling-car-head-title-eta { |
| | | font-size: 40px; |
| | | font-weight: 500; |
| | | color: #6d7fd9; |
| | | margin: 0 4px; |
| | | line-height: 44px; |
| | | } |
| | | } |
| | | |
| | |
| | | .calling-car { |
| | | position: relative; |
| | | z-index: 9; |
| | | padding: 40px 42px 88px 34px; |
| | | padding: 40px 24px 80px 24px; |
| | | background: #f2f3f7; |
| | | border-top: 2px solid #fff; |
| | | border-radius: 40px 40px 0 0; |
| | |
| | | .car-card { |
| | | position: relative; |
| | | z-index: 1; |
| | | margin-top: 28px; |
| | | margin-top: 32px; |
| | | border-radius: 24px; |
| | | background: #ffffff; |
| | | padding: 31.29px 32px 36px 33px; |
| | | padding: 32px 16px 32px 36px; |
| | | |
| | | .car-card-line { |
| | | margin-top: 29.29px; |
| | | margin-bottom: 36px; |
| | | height: 1px; |
| | | background-color: rgba(0, 0, 0, 0.07); |
| | | margin-top: 11px; |
| | | margin-bottom: 29px; |
| | | margin-left: 6px; |
| | | width: 624px; |
| | | height: 0.01px; |
| | | background-color: rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | &-detail { |
| | |
| | | font-size: 48px; |
| | | line-height: 64px; |
| | | letter-spacing: normal; |
| | | font-weight: 500; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | |
| | | &-img { |
| | | flex-shrink: 0; |
| | | width: 300px; |
| | | height: 141.43px; |
| | | height: 140px; |
| | | } |
| | | } |
| | | |
| | | &-temp { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | .car-card-temp { |
| | | &-list { |
| | | width: 100%; |
| | | padding-right: 22px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | position: relative; |
| | | } |
| | | |
| | | &-title { |
| | | font-size: 28px; |
| | | &-img { |
| | | position: absolute; |
| | | top: 28px; |
| | | left: 5px; |
| | | width: 2px; |
| | | height: 47px; |
| | | transform: translateX(50%); |
| | | } |
| | | |
| | | &-row { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | &-left { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .dot { |
| | | width: 12px; |
| | | height: 12px; |
| | | border-radius: 50%; |
| | | margin-right: 12px; |
| | | flex-shrink: 0; |
| | | |
| | | &.start { |
| | | background: #768aff; |
| | | } |
| | | &.end { |
| | | background: #8bb654; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .car-card-temp-title { |
| | | font-size: 24px; |
| | | line-height: 40px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | &-content { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 24px; |
| | | |
| | | &-text { |
| | | font-size: 56px; |
| | | line-height: 72px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | text-align: center; |
| | | } |
| | | |
| | | &-img { |
| | | width: 56px; |
| | | height: 56px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-arrive { |
| | | margin-top: 36px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 30px; |
| | | height: 156px; |
| | | text-align: center; |
| | | font-size: 24px; |
| | | line-height: 40px; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | |
| | | &-item { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 8px; |
| | | padding: 22px 0; |
| | | |
| | | &:first-child { |
| | | position: relative; |
| | | border-radius: 16px; |
| | | background: #ffffff; |
| | | box-sizing: border-box; |
| | | border: 2px solid rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | &:last-child { |
| | | border-radius: 16px; |
| | | background: #ffffff; |
| | | box-sizing: border-box; |
| | | border: 2px solid rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | &-img { |
| | | width: 64px; |
| | | height: 64px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-end { |
| | | &-particulars { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | &-money { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | view:nth-child(1) { |
| | | font-size: 48px; |
| | | line-height: 40px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | view:nth-child(2) { |
| | | margin: 0 4px; |
| | | font-size: 24px; |
| | | line-height: 36px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | view:nth-child(3) { |
| | | font-size: 28px; |
| | | line-height: 36px; |
| | | letter-spacing: normal; |
| | | text-decoration: line-through; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | |
| | | view:nth-child(4) { |
| | | margin-left: 8px; |
| | | border-radius: 8px; |
| | | box-sizing: border-box; |
| | | border: 2px solid #f58900; |
| | | padding: 0 12px; |
| | | line-height: 34px; |
| | | font-size: 20px; |
| | | font-weight: 500; |
| | | letter-spacing: normal; |
| | | color: #f58900; |
| | | } |
| | | } |
| | | |
| | | &-view { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 24px; |
| | | letter-spacing: normal; |
| | | &.disabled-text { |
| | | color: rgba(0, 0, 0, 0.4); |
| | | |
| | | image { |
| | | margin-left: 4px; |
| | | width: 32px; |
| | | height: 32px; |
| | | transition: transform 0.3s ease-in-out; |
| | | |
| | | &.rotate { |
| | | transform: rotate(90deg); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .particulars-detail { |
| | | border-radius: 16px; |
| | | background: #f5f6fa; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 16px; |
| | | overflow: auto; |
| | | |
| | | max-height: 0; |
| | | margin-top: 0; |
| | | margin-bottom: 0; |
| | | padding: 0 32px; |
| | | opacity: 0; |
| | | transition: all 0.3s ease-in-out; |
| | | |
| | | &.expand { |
| | | max-height: 600px; |
| | | margin-top: 24px; |
| | | margin-bottom: 16px; |
| | | padding: 24px 32px; |
| | | opacity: 1; |
| | | } |
| | | |
| | | &-item { |
| | | width: 100%; |
| | | |
| | | &-title { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 24px; |
| | | line-height: 40px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | |
| | | .color1 { |
| | | color: #f58900; |
| | | } |
| | | } |
| | | |
| | | &-content { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 20px; |
| | | line-height: 36px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-cost { |
| | | margin-top: 32px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | &-money { |
| | | font-size: 24px; |
| | | line-height: 44px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | &-view { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 24px; |
| | | letter-spacing: normal; |
| | | .car-card-temp-time { |
| | | font-size: 24px; |
| | | line-height: 40px; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | &.disabled-text { |
| | | color: rgba(0, 0, 0, 0.4); |
| | | |
| | | image { |
| | | margin-left: 4px; |
| | | width: 32px; |
| | | height: 32px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-pay { |
| | | margin-left: 30px; |
| | | margin-right: 36px; |
| | | margin-top: 60px; |
| | | border-radius: 16px; |
| | | background: linear-gradient(97deg, #8475ff 0%, #7dd6ff 103%); |
| | | line-height: 96px; |
| | | text-align: center; |
| | | font-size: 30px; |
| | | letter-spacing: normal; |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .custom-callout { |
| | | position: relative; |
| | | z-index: 999; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .pd-6-10 { |
| | | padding: 8px 20px !important; |
| | | } |
| | | |
| | | .waiting-callout-content { |
| | | z-index: 2; |
| | | position: absolute; |
| | | top: 240px; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | } |
| | | |
| | | .custom-callout-content { |
| | | display: flex; |
| | | align-items: center; |
| | | white-space: nowrap; |
| | | border-radius: 16px; |
| | | background: rgba(255, 255, 255, 1); |
| | | font-size: 24px; |
| | | font-weight: 400; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | line-height: 38px; |
| | | box-shadow: 0px 4px 16px 0px rgba(45, 48, 64, 0.2); |
| | | padding: 8px 20px; |
| | | } |
| | | |
| | | .txt-center { |
| | | text-align: center; |
| | | } |
| | | |
| | | .car-time { |
| | | font-size: 24px; |
| | | letter-spacing: normal; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .car-time-num { |
| | | font-size: 36px; |
| | | letter-spacing: normal; |
| | | color: #6D7FD9; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .custom-callout-icon { |
| | | width: 32px; |
| | | height: 32px; |
| | | flex-shrink: 0; |
| | | display: block; |
| | | } |
| | | |
| | | .car-callout-android { |
| | | z-index: 9; |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .waiting-callout { |
| | | position: relative; |
| | | z-index: 999; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | justify-content: flex-start; |
| | | overflow: visible; // 确保辐射动画不被裁剪 |
| | | min-width: 700px; |
| | | height: 600px; |
| | | } |
| | | |
| | | .waiting-radar { |
| | | position: absolute; |
| | | bottom: 50px; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 350px; |
| | | pointer-events: none; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .waiting-radar-img { |
| | | position: fixed; |
| | | width: 700px; |
| | | height: 350px; |
| | | top: 48%; |
| | | left: 50%; |
| | | transform: translate(-50%, -48%); |
| | | } |
| | | |
| | | .waiting-callout-bg { |
| | | position: relative; |
| | | height: 70px; |
| | | min-width: 155px; |
| | | text-align: center; |
| | | display: flex; |
| | | align-items: flex-start; |
| | | justify-content: center; |
| | | width: fit-content; |
| | | } |
| | | |
| | | .waiting-callout-bg-img { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .waiting-callout-bg-text { |
| | | position: relative; |
| | | z-index: 100; |
| | | font-size: 22px; |
| | | font-weight: 400; |
| | | letter-spacing: normal; |
| | | color: #FFFFFF; |
| | | line-height: 48px; |
| | | padding: 0 20px; |
| | | box-sizing: border-box; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .waiting-callout-txt { |
| | | z-index: 200; |
| | | border-radius: 16px; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | font-size: 24px; |
| | | font-weight: 400; |
| | | background: rgba(255, 255, 255, 1); |
| | | padding: 8px 20px; |
| | | line-height: 48px; |
| | | display: flex; |
| | | } |
| | | |
| | | .pr-6 { |
| | | padding-right: 6px; |
| | | } |
| | | |
| | | .pr-0 { |
| | | padding-right: 0; |
| | | } |
| | |
| | | import Taro from "@tarojs/taro"; |
| | | import { View, Text, Image, Map } from "@tarojs/components"; |
| | | import { useState, useEffect } from "react"; |
| | | import { View, Image, Map } from "@tarojs/components"; |
| | | import { useState, useEffect, useMemo, useRef } from "react"; |
| | | import "./index.less"; |
| | | |
| | | import homeIcon from "../../assets/back-home.png"; // 占位,建议换成首页小房子图标 |
| | | import pointer from "../../assets/pointer.png"; // 车辆图标 |
| | | import shareContactIcon from "../../assets/share-contact.png"; // 客服占位图 |
| | | import contactServiceIcon from "../../assets/contact-service.png"; // 客服占位图 |
| | | import shareLine from "../../assets/share-line.png"; // 分享线占位图 |
| | | |
| | | // 地图标记状态管理 |
| | | import useMapMarkers from '../begin-route/hooks/use-map-markers'; |
| | | // 车辆追踪状态管理 |
| | | import useVehicleTracking from '../begin-route/hooks/use-vehicle-tracking'; |
| | | // 路线渲染状态管理 |
| | | import useRouteManager from "../begin-route/hooks/use-route-manager"; |
| | | // 地图覆盖物渲染委托 |
| | | import useViewDelegates from "../begin-route/hooks/use-view-delegates"; |
| | | |
| | | export default function ShareTrip() { |
| | | const [tripData, setTripData] = useState<any>(null); |
| | | const [longitude, setLongitude] = useState(113.32452); |
| | | const [latitude, setLatitude] = useState(23.10229); |
| | | const [startSite, setStartSite] = useState<any>(null); // 上车点 |
| | | const [endSite, setEndSite] = useState<any>({}); // 下车点 |
| | | const [isExpired, setIsExpired] = useState(false); // 是否已过期(大于24小时) |
| | | const [showReminder, setShowReminder] = useState(true); // 模拟是否显示提醒 |
| | | const [tripStatus, setTripStatus] = useState<number>(1); // 行程状态 1:发布行程 2:发布中 3:呼叫车中 4:车辆即将到达 5:车辆到达上车点 6:车辆行驶中 7:到达目的地 8:行程已结束 9:支付成功 10:取消订单时页面只展示一个上车点 |
| | | const tripStatusRef = useRef(tripStatus); |
| | | // 行程状态显示规则配置:showPickup-显示上车点,showDropoff-显示下车点,showCar-显示车辆,showRoute-显示路线,showWalking-显示步行路线,viewport-视口类型,translateCar-车辆是否平移 |
| | | const STATUS_RULES: Record<number, any> = { |
| | | 1: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: true, viewport: 'route_walking', translateCar: false }, |
| | | 2: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false }, |
| | | 3: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false }, |
| | | 4: { showPickup: true, showDropoff: false, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true }, |
| | | 5: { showPickup: true, showDropoff: false, showCar: true, showRoute: false, showWalking: false, viewport: 'car_user', translateCar: true }, |
| | | 6: { showPickup: false, showDropoff: true, showCar: true, showRoute: true, showWalking: false, viewport: 'route', translateCar: true }, |
| | | 7: { showPickup: false, showDropoff: true, showCar: false, showRoute: false, showWalking: false, viewport: 'dropoff', translateCar: false }, |
| | | 8: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false }, |
| | | 9: { showPickup: true, showDropoff: true, showCar: false, showRoute: true, showWalking: false, viewport: 'order_detail', translateCar: false }, |
| | | 10: { showPickup: true, showDropoff: false, showCar: false, showRoute: false, showWalking: false, viewport: 'pickup', translateCar: false }, |
| | | }; |
| | | const statusRule = useMemo(() => STATUS_RULES[tripStatus] || STATUS_RULES[1], [tripStatus]); // 当前行程状态对应的显示规则 |
| | | const shouldShowRoute = statusRule.showRoute; |
| | | const isAndroid = useMemo(() => { |
| | | try { |
| | | const info = Taro.getSystemInfoSync(); |
| | | return info?.platform === 'android' || /android/i.test(info?.system || ''); |
| | | } catch (error) { |
| | | return false; |
| | | } |
| | | }, []); |
| | | const mapLongitude = longitude ?? 116.397128; |
| | | const mapLatitude = latitude ?? 39.916527; |
| | | const vehicleMarkerId = !isAndroid && tripStatus === 6 ? 30 : 3; |
| | | const vehicleState = useVehicleTracking({ |
| | | statusRule, |
| | | vehicleMarkerId |
| | | }); // 车辆追踪状态容器 |
| | | const { |
| | | vehicleLocation, |
| | | vehicleDirection, |
| | | setVehicleDirection, |
| | | updateVehicleLocationThrottled, |
| | | } = vehicleState; // 车辆状态解构 |
| | | |
| | | const markerState = useMapMarkers({ |
| | | tripStatus, |
| | | statusRule, |
| | | isAndroid, |
| | | startSite, |
| | | endSite, |
| | | vehicleLocation, |
| | | vehicleDirection, |
| | | vehicleMarkerId |
| | | }); // 地图标记状态容器 |
| | | const { |
| | | markers |
| | | } = markerState; // 标记状态解构 |
| | | |
| | | const routeState = useRouteManager({ |
| | | isAndroid, |
| | | tripStatus, |
| | | tripStatusRef, |
| | | statusRule, |
| | | shouldShowRoute, |
| | | startSite, |
| | | updateVehicleLocationThrottled, |
| | | setVehicleDirection |
| | | }); |
| | | const { |
| | | polyline, |
| | | applyRoutePoints, |
| | | routeDistance, |
| | | routeDuration, |
| | | setRouteDistance, |
| | | setRouteDuration |
| | | } = routeState; |
| | | const applyRoutePointsRef = useRef(applyRoutePoints); |
| | | const updateVehicleLocationRef = useRef(updateVehicleLocationThrottled); |
| | | const setVehicleDirectionRef = useRef(setVehicleDirection); |
| | | |
| | | const mockScene = useMemo(() => { |
| | | const drivingTrack = [ |
| | | { longitude: 104.055501, latitude: 30.586747 }, { longitude: 104.05551, latitude: 30.586678 }, { longitude: 104.055537, latitude: 30.58657 }, { longitude: 104.055548, latitude: 30.58656 }, { longitude: 104.055821, latitude: 30.586565 }, { longitude: 104.056191, latitude: 30.58657 }, |
| | | { longitude: 104.056191, latitude: 30.58657 }, { longitude: 104.056202, latitude: 30.586426 }, { longitude: 104.056218, latitude: 30.586189 }, { longitude: 104.056234, latitude: 30.585938 }, { longitude: 104.056256, latitude: 30.58568 }, { longitude: 104.056261, latitude: 30.585562 }, |
| | | { longitude: 104.056261, latitude: 30.585562 }, { longitude: 104.055741, latitude: 30.58554 }, { longitude: 104.055467, latitude: 30.585524 }, { longitude: 104.05477, latitude: 30.585492 }, { longitude: 104.054501, latitude: 30.585476 }, { longitude: 104.054405, latitude: 30.585476 }, |
| | | { longitude: 104.053869, latitude: 30.585438 }, { longitude: 104.053488, latitude: 30.585417 }, { longitude: 104.053359, latitude: 30.585412 }, { longitude: 104.053074, latitude: 30.585396 }, { longitude: 104.05117, latitude: 30.585288 }, { longitude: 104.050693, latitude: 30.585267 }, |
| | | { longitude: 104.050328, latitude: 30.585245 }, { longitude: 104.050221, latitude: 30.58524 }, { longitude: 104.049604, latitude: 30.585208 }, { longitude: 104.049046, latitude: 30.585176 }, { longitude: 104.048853, latitude: 30.585165 }, { longitude: 104.04859, latitude: 30.585154 }, |
| | | { longitude: 104.048354, latitude: 30.585133 }, { longitude: 104.048273, latitude: 30.585122 }, { longitude: 104.048134, latitude: 30.585117 }, { longitude: 104.048005, latitude: 30.585133 }, { longitude: 104.047565, latitude: 30.585111 }, { longitude: 104.046616, latitude: 30.585068 }, |
| | | { longitude: 104.046616, latitude: 30.585068 }, { longitude: 104.046637, latitude: 30.585938 }, { longitude: 104.046643, latitude: 30.586061 }, { longitude: 104.046669, latitude: 30.586366 }, { longitude: 104.046723, latitude: 30.586753 }, { longitude: 104.046798, latitude: 30.587128 }, |
| | | { longitude: 104.046911, latitude: 30.587777 }, { longitude: 104.046954, latitude: 30.587965 }, { longitude: 104.046986, latitude: 30.58811 }, { longitude: 104.046653, latitude: 30.588319 }, { longitude: 104.046653, latitude: 30.588319 }, { longitude: 104.045741, latitude: 30.588276 }, |
| | | { longitude: 104.044942, latitude: 30.588255 }, { longitude: 104.043156, latitude: 30.588212 }, { longitude: 104.042185, latitude: 30.588191 }, { longitude: 104.041493, latitude: 30.588169 }, { longitude: 104.040527, latitude: 30.588137 }, { longitude: 104.039921, latitude: 30.588121 }, |
| | | { longitude: 104.038483, latitude: 30.588089 }, { longitude: 104.037518, latitude: 30.588089 }, { longitude: 104.037298, latitude: 30.588083 }, { longitude: 104.037121, latitude: 30.588072 }, { longitude: 104.035951, latitude: 30.588051 }, { longitude: 104.035565, latitude: 30.588072 }, |
| | | { longitude: 104.035511, latitude: 30.588078 }, { longitude: 104.0352, latitude: 30.58811 }, { longitude: 104.034599, latitude: 30.588164 }, { longitude: 104.034213, latitude: 30.588212 }, { longitude: 104.033843, latitude: 30.588276 }, { longitude: 104.033382, latitude: 30.5884 }, |
| | | { longitude: 104.033382, latitude: 30.5884 }, { longitude: 104.033452, latitude: 30.588587 }, { longitude: 104.033602, latitude: 30.58892 }, { longitude: 104.033763, latitude: 30.589279 }, { longitude: 104.034015, latitude: 30.590776 }, { longitude: 104.034026, latitude: 30.591709 }, |
| | | { longitude: 104.034031, latitude: 30.592219 }, { longitude: 104.033966, latitude: 30.593786 }, { longitude: 104.033961, latitude: 30.59459 }, { longitude: 104.033977, latitude: 30.595604 }, { longitude: 104.033961, latitude: 30.595931 }, { longitude: 104.033972, latitude: 30.596924 }, |
| | | { longitude: 104.033972, latitude: 30.596951 }, { longitude: 104.033972, latitude: 30.596951 }, { longitude: 104.034423, latitude: 30.596972 }, { longitude: 104.034423, latitude: 30.596972 }, { longitude: 104.034423, latitude: 30.596924 }, { longitude: 104.034433, latitude: 30.596768 }, |
| | | { longitude: 104.034444, latitude: 30.595443 }, { longitude: 104.034449, latitude: 30.594295 }, { longitude: 104.034481, latitude: 30.594172 }, { longitude: 104.034594, latitude: 30.594022 }, { longitude: 104.034755, latitude: 30.593871 }, { longitude: 104.034755, latitude: 30.593871 }, |
| | | { longitude: 104.033339, latitude: 30.592729 }, { longitude: 104.032915, latitude: 30.592417 }, { longitude: 104.032792, latitude: 30.592326 }, { longitude: 104.03262, latitude: 30.592187 }, { longitude: 104.032084, latitude: 30.591758 }, { longitude: 104.031402, latitude: 30.591211 }, |
| | | { longitude: 104.031343, latitude: 30.591168 }, { longitude: 104.030957, latitude: 30.590857 }, { longitude: 104.030769, latitude: 30.590706 }, { longitude: 104.030281, latitude: 30.590309 }, { longitude: 104.030169, latitude: 30.590218 }, { longitude: 104.030104, latitude: 30.590164 }, |
| | | { longitude: 104.02975, latitude: 30.58988 }, { longitude: 104.028828, latitude: 30.58914 }, { longitude: 104.027964, latitude: 30.588448 }, { longitude: 104.027175, latitude: 30.587809 }, { longitude: 104.026794, latitude: 30.587509 }, { longitude: 104.026639, latitude: 30.587386 }, |
| | | { longitude: 104.026639, latitude: 30.587386 }, { longitude: 104.026623, latitude: 30.587327 }, { longitude: 104.026558, latitude: 30.587219 }, { longitude: 104.026172, latitude: 30.586806 }, { longitude: 104.02614, latitude: 30.586764 }, { longitude: 104.026124, latitude: 30.586704 }, |
| | | { longitude: 104.02518, latitude: 30.585938 }, { longitude: 104.020545, latitude: 30.582214 }, { longitude: 104.019338, latitude: 30.581244 }, { longitude: 104.018721, latitude: 30.580745 }, { longitude: 104.018554, latitude: 30.580611 }, { longitude: 104.017111, latitude: 30.579468 }, |
| | | { longitude: 104.016731, latitude: 30.579194 }, { longitude: 104.016307, latitude: 30.578921 }, { longitude: 104.015937, latitude: 30.578701 }, { longitude: 104.015556, latitude: 30.578508 }, { longitude: 104.015175, latitude: 30.57832 }, { longitude: 104.014628, latitude: 30.578073 }, |
| | | { longitude: 104.014, latitude: 30.577848 }, { longitude: 104.013217, latitude: 30.577617 }, { longitude: 104.012664, latitude: 30.577483 }, { longitude: 104.011731, latitude: 30.577306 }, { longitude: 104.003899, latitude: 30.575938 }, { longitude: 104.002306, latitude: 30.575659 }, |
| | | { longitude: 104.001474, latitude: 30.575509 }, { longitude: 103.998926, latitude: 30.575085 }, { longitude: 103.998213, latitude: 30.574951 }, { longitude: 103.996582, latitude: 30.574661 }, { longitude: 103.995933, latitude: 30.574549 }, { longitude: 103.982232, latitude: 30.572146 }, |
| | | { longitude: 103.979244, latitude: 30.57162 }, { longitude: 103.978327, latitude: 30.571464 }, { longitude: 103.977592, latitude: 30.571351 }, { longitude: 103.977093, latitude: 30.571292 }, { longitude: 103.975339, latitude: 30.570965 }, { longitude: 103.974609, latitude: 30.570831 }, |
| | | { longitude: 103.973644, latitude: 30.570665 }, { longitude: 103.972834, latitude: 30.570536 }, { longitude: 103.972024, latitude: 30.570413 }, { longitude: 103.972024, latitude: 30.570413 }, { longitude: 103.971949, latitude: 30.570391 }, { longitude: 103.971788, latitude: 30.570364 }, |
| | | { longitude: 103.971353, latitude: 30.570327 }, { longitude: 103.970994, latitude: 30.570322 }, { longitude: 103.970725, latitude: 30.570327 }, { longitude: 103.970436, latitude: 30.570343 }, { longitude: 103.970151, latitude: 30.570375 }, { longitude: 103.969513, latitude: 30.570483 }, |
| | | { longitude: 103.968515, latitude: 30.57067 }, { longitude: 103.967807, latitude: 30.570826 }, { longitude: 103.967807, latitude: 30.570826 }, { longitude: 103.966986, latitude: 30.571024 }, { longitude: 103.966707, latitude: 30.571105 }, { longitude: 103.966053, latitude: 30.57133 }, |
| | | { longitude: 103.965243, latitude: 30.571609 }, { longitude: 103.964986, latitude: 30.571706 }, { longitude: 103.964691, latitude: 30.571824 }, { longitude: 103.964309, latitude: 30.571952 }, { longitude: 103.963966, latitude: 30.572076 }, { longitude: 103.963891, latitude: 30.572102 }, |
| | | { longitude: 103.963687, latitude: 30.572162 }, { longitude: 103.963548, latitude: 30.572215 }, { longitude: 103.963146, latitude: 30.572355 }, { longitude: 103.962518, latitude: 30.572575 }, { longitude: 103.961981, latitude: 30.572784 }, { longitude: 103.961418, latitude: 30.572998 }, |
| | | { longitude: 103.961418, latitude: 30.572998 }, { longitude: 103.961225, latitude: 30.5731 }, { longitude: 103.96108, latitude: 30.57317 }, { longitude: 103.960157, latitude: 30.573481 }, { longitude: 103.959401, latitude: 30.573728 }, { longitude: 103.959031, latitude: 30.573808 }, |
| | | { longitude: 103.958956, latitude: 30.573824 }, { longitude: 103.958382, latitude: 30.573894 }, { longitude: 103.95828, latitude: 30.573766 }, { longitude: 103.95828, latitude: 30.573766 }, { longitude: 103.958135, latitude: 30.573261 }, { longitude: 103.95791, latitude: 30.572816 }, |
| | | { longitude: 103.957422, latitude: 30.571749 }, { longitude: 103.957229, latitude: 30.571319 }, { longitude: 103.956955, latitude: 30.570729 }, { longitude: 103.95681, latitude: 30.570418 }, { longitude: 103.956751, latitude: 30.570284 }, { longitude: 103.956569, latitude: 30.569914 }, |
| | | { longitude: 103.956435, latitude: 30.569619 }, { longitude: 103.956309, latitude: 30.569347 } |
| | | ]; |
| | | |
| | | const pickupSite = { |
| | | name: "上车点", |
| | | latitude: drivingTrack[0].latitude, |
| | | longitude: drivingTrack[0].longitude |
| | | }; |
| | | const dropoffSite = { |
| | | name: "目的地", |
| | | latitude: drivingTrack[drivingTrack.length - 1].latitude, |
| | | longitude: drivingTrack[drivingTrack.length - 1].longitude |
| | | }; |
| | | // 使用路线起点附近的一小段倒放,模拟车辆靠近上车点 |
| | | const pickupTrack = drivingTrack.slice(0, 10).reverse().map(item => ({ ...item })); |
| | | const centerPoint = drivingTrack[Math.floor(drivingTrack.length / 2)]; |
| | | |
| | | return { |
| | | pickupSite, |
| | | dropoffSite, |
| | | pickupTrack, |
| | | drivingTrack, |
| | | centerPoint |
| | | }; |
| | | }, []); |
| | | |
| | | const getDirectionByPoints = (from: { latitude: number; longitude: number }, to?: { latitude: number; longitude: number }) => { |
| | | if (!from || !to) return 0; |
| | | const deltaLng = to.longitude - from.longitude; |
| | | const deltaLat = to.latitude - from.latitude; |
| | | const angle = Math.atan2(deltaLng, deltaLat) * (180 / Math.PI); |
| | | return ((angle % 360) + 360) % 360; |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | // TODO: 替换为真实的获取分享行程数据的接口 |
| | | setTimeout(() => { |
| | | tripStatusRef.current = tripStatus; |
| | | }, [tripStatus]); |
| | | |
| | | useEffect(() => { |
| | | applyRoutePointsRef.current = applyRoutePoints; |
| | | updateVehicleLocationRef.current = updateVehicleLocationThrottled; |
| | | setVehicleDirectionRef.current = setVehicleDirection; |
| | | }, [applyRoutePoints, updateVehicleLocationThrottled, setVehicleDirection]); |
| | | |
| | | useEffect(() => { |
| | | setShowReminder(false); |
| | | setStartSite(mockScene.pickupSite); |
| | | setEndSite(mockScene.dropoffSite); |
| | | setLongitude(mockScene.centerPoint.longitude); |
| | | setLatitude(mockScene.centerPoint.latitude); |
| | | |
| | | let stage = "pickup"; |
| | | let pointIndex = 0; |
| | | |
| | | const syncMockTripData = (nextStatus: number, etaMinutes: number) => { |
| | | const remainDistance = |
| | | nextStatus === 4 |
| | | ? { value: Math.max(0.5, Number((etaMinutes * 0.8).toFixed(1))), unit: "km" as const } |
| | | : nextStatus === 6 |
| | | ? { value: Math.max(0.5, Number(((mockScene.drivingTrack.length - pointIndex) * 0.6).toFixed(1))), unit: "km" as const } |
| | | : { value: 0, unit: "km" as const }; |
| | | const remainDuration = nextStatus === 7 ? 0 : Math.max(60, etaMinutes * 60); |
| | | |
| | | setTripStatus(nextStatus); |
| | | setRouteDistance(remainDistance); |
| | | setRouteDuration(remainDuration); |
| | | setTripData({ |
| | | etaMinutes: 4, |
| | | distanceText: "3.6公里", |
| | | etaMinutes, |
| | | distanceText: `${remainDistance.value}${remainDistance.unit}`, |
| | | plateNumber: "粤PXV7029", |
| | | vehicleColor: "白色", |
| | | vehicleCode: "03", |
| | | vehicleImage: "https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/car-g9.png", // 占位图 |
| | | startName: "广州岭南职业技术学院-(公交站)", |
| | | endName: "小鹏科技园2号楼", |
| | | carLat: 23.10229, |
| | | carLng: 113.32452 |
| | | vehicleImage: "https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/car-g9.png", |
| | | startName: mockScene.pickupSite.name, |
| | | endName: mockScene.dropoffSite.name, |
| | | tripStatus: nextStatus, |
| | | boardTime: nextStatus >= 6 ? "14:56" : null, |
| | | arriveTime: nextStatus === 7 ? "15:10" : null |
| | | }); |
| | | }, 1000); |
| | | }, []); |
| | | }; |
| | | |
| | | // 初始化一段路线,先验证 hooks 产出的 polyline 是否可用 |
| | | applyRoutePointsRef.current(mockScene.pickupTrack); |
| | | updateVehicleLocationRef.current( |
| | | mockScene.pickupTrack[0].latitude, |
| | | mockScene.pickupTrack[0].longitude, |
| | | true |
| | | ); |
| | | syncMockTripData(4, 4); |
| | | |
| | | const intervalId = setInterval(() => { |
| | | if (stage === "pickup") { |
| | | const currentPoint = mockScene.pickupTrack[pointIndex]; |
| | | const nextPoint = mockScene.pickupTrack[pointIndex + 1]; |
| | | const remainPoints = mockScene.pickupTrack.slice(pointIndex); |
| | | |
| | | if (currentPoint) { |
| | | applyRoutePointsRef.current(remainPoints.length ? remainPoints : [currentPoint]); |
| | | updateVehicleLocationRef.current(currentPoint.latitude, currentPoint.longitude, true); |
| | | setVehicleDirectionRef.current(getDirectionByPoints(currentPoint, nextPoint)); |
| | | syncMockTripData(4, Math.max(1, mockScene.pickupTrack.length - pointIndex - 1)); |
| | | } |
| | | |
| | | if (pointIndex >= mockScene.pickupTrack.length - 1) { |
| | | stage = "driving"; |
| | | pointIndex = 0; |
| | | applyRoutePointsRef.current(mockScene.drivingTrack); |
| | | syncMockTripData(6, 0); |
| | | return; |
| | | } |
| | | |
| | | pointIndex += 1; |
| | | return; |
| | | } |
| | | |
| | | if (stage === "driving") { |
| | | const currentPoint = mockScene.drivingTrack[pointIndex]; |
| | | const nextPoint = mockScene.drivingTrack[pointIndex + 1]; |
| | | const remainPoints = mockScene.drivingTrack.slice(pointIndex); |
| | | |
| | | if (currentPoint) { |
| | | applyRoutePointsRef.current(remainPoints.length ? remainPoints : [currentPoint]); |
| | | updateVehicleLocationRef.current(currentPoint.latitude, currentPoint.longitude, true); |
| | | setVehicleDirectionRef.current(getDirectionByPoints(currentPoint, nextPoint)); |
| | | syncMockTripData(6, 0); |
| | | } |
| | | |
| | | if (pointIndex >= mockScene.drivingTrack.length - 1) { |
| | | stage = "arrived"; |
| | | syncMockTripData(7, 0); |
| | | return; |
| | | } |
| | | |
| | | pointIndex += 1; |
| | | } |
| | | }, 2000); |
| | | |
| | | return () => clearInterval(intervalId); |
| | | }, [mockScene, setRouteDistance, setRouteDuration]); |
| | | |
| | | const goHome = () => { |
| | | Taro.reLaunch({ url: "/pages/robotaxi/home/index" }); |
| | | }; |
| | | const { renderMapOverlays } = useViewDelegates({ |
| | | isAndroid, |
| | | tripStatus, |
| | | markers, |
| | | shouldShowWaitingRadar: false, |
| | | waitingRadarVisible: false, |
| | | waitingRadarStyle: {}, |
| | | waitingRadarSrc: "", |
| | | carCalloutVisible: false, |
| | | carCalloutStyle: {}, |
| | | arriveCalloutVisible: false, |
| | | arriveCalloutStyle: {}, |
| | | routeDistance, |
| | | routeDuration, |
| | | customCalloutIconSrc: "https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-tooltip-right.png", |
| | | startSite, |
| | | endSite, |
| | | callImmediately: () => {}, |
| | | fareEstimate: {}, |
| | | handleOpenPassengerNotice: () => {}, |
| | | walkingTime: 0, |
| | | isCallDisabled: false, |
| | | handleOpenCancelPopupByTripStatus: () => {}, |
| | | handleOpenCancelPopupWithType: () => {}, |
| | | setTripStatus, |
| | | finishCountdownEnabled: false, |
| | | orderId: "", |
| | | vehicleInfo: {}, |
| | | handleFinishCountdownTimeout: () => {}, |
| | | resetDetailVersion: 0, |
| | | priceUpdateVersion: 0, |
| | | evaluateSubmitVersion: 0, |
| | | evaluateCloseVersion: 0, |
| | | handleOpenAnnouncementsPopup: () => {}, |
| | | handleOpenOverRoutePopup: () => {}, |
| | | handlePay: () => {}, |
| | | handleOpenEvaluatePopup: () => {}, |
| | | handleToggleDetailFade: () => {}, |
| | | isRouteSelectExpanded: false, |
| | | onToggleRouteSelect: () => {}, |
| | | trunkStatus: false |
| | | }); |
| | | |
| | | const markers = tripData |
| | | ? [ |
| | | { |
| | | id: 1, |
| | | latitude: tripData.carLat, |
| | | longitude: tripData.carLng, |
| | | iconPath: pointer, |
| | | width: 32, |
| | | height: 32, |
| | | anchor: { x: 0.5, y: 0.5 }, |
| | | callout: { |
| | | content: `${tripData.distanceText} ${tripData.etaMinutes}分钟`, |
| | | color: "#6D7FD9", |
| | | fontSize: 12, |
| | | borderRadius: 12, |
| | | bgColor: "#ffffff", |
| | | padding: 6, |
| | | display: "ALWAYS" |
| | | } |
| | | } |
| | | ] |
| | | : []; |
| | | // const renderMarkers = () => { |
| | | // if (!tripData) return []; |
| | | // const markersList: any[] = []; |
| | | |
| | | // // 上车点 (等待接驾、行程中显示) |
| | | // if (tripData.tripStatus === 1 || tripData.tripStatus === 2) { |
| | | // markersList.push({ |
| | | // id: 1, |
| | | // latitude: tripData.startLat, |
| | | // longitude: tripData.startLng, |
| | | // iconPath: "https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-up.png", |
| | | // width: 22, |
| | | // height: 40, |
| | | // anchor: { x: 0.5, y: 1 }, |
| | | // zIndex: 1, |
| | | // name: tripData.startName |
| | | // }); |
| | | // } |
| | | |
| | | // // 下车点 (始终显示) |
| | | // markersList.push({ |
| | | // id: 2, |
| | | // latitude: tripData.endLat, |
| | | // longitude: tripData.endLng, |
| | | // iconPath: "https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-down.png", |
| | | // width: 22, |
| | | // height: 40, |
| | | // anchor: { x: 0.5, y: 1 }, |
| | | // zIndex: 1, |
| | | // name: tripData.endName |
| | | // }); |
| | | |
| | | // // 车辆 (等待接驾、行程中显示) |
| | | // if ( |
| | | // vehicleLocation && |
| | | // (tripData.tripStatus === 1 || tripData.tripStatus === 2) |
| | | // ) { |
| | | // markersList.push({ |
| | | // id: 3, |
| | | // latitude: vehicleLocation.latitude, |
| | | // longitude: vehicleLocation.longitude, |
| | | // iconPath: carIcon, |
| | | // width: 46, |
| | | // height: 71, |
| | | // anchor: { x: 0.5, y: 0.5 }, |
| | | // rotate: vehicleDirection, |
| | | // zIndex: 2, |
| | | // callout: |
| | | // tripData.tripStatus === 1 |
| | | // ? { |
| | | // content: `${tripData.distanceText} ${tripData.etaMinutes}分钟`, |
| | | // color: "#6D7FD9", |
| | | // fontSize: 12, |
| | | // borderRadius: 12, |
| | | // bgColor: "#ffffff", |
| | | // padding: 6, |
| | | // display: "ALWAYS" |
| | | // } |
| | | // : undefined |
| | | // }); |
| | | // } |
| | | |
| | | // return markersList; |
| | | // }; |
| | | |
| | | // const markers = renderMarkers(); |
| | | |
| | | const handleContactService = () => { |
| | | // 唤起客服操作 |
| | | Taro.makePhoneCall({ |
| | | phoneNumber: "400-000-0000" // TODO: 替换为实际客服电话 |
| | | }).catch(() => {}); |
| | | }; |
| | | |
| | | if (isExpired) { |
| | | return ( |
| | | <View className="share-trip-expired"> |
| | | <View className="expired-content"> |
| | | <Image className="expired-img" src={shareContactIcon} /> |
| | | <View className="expired-text">行程结束已超过24小时</View> |
| | | <View className="expired-sub-text">查看行程信息,请联系客服</View> |
| | | <View className="expired-btn" onClick={handleContactService}> |
| | | 联系客服 |
| | | </View> |
| | | </View> |
| | | </View> |
| | | ); |
| | | } |
| | | |
| | | return ( |
| | | <View className="home-container"> |
| | | <Map |
| | | {/* <Map |
| | | className="map-container" |
| | | longitude={longitude} |
| | | latitude={latitude} |
| | | scale={14} |
| | | markers={markers} |
| | | polyline={tripData?.tripStatus === 1 || tripData?.tripStatus === 2 ? polyline : []} |
| | | style={{ width: "100%", height: "100%" }} |
| | | > */} |
| | | <Map |
| | | id="map" |
| | | longitude={mapLongitude} |
| | | latitude={mapLatitude} |
| | | scale={14} |
| | | markers={markers} |
| | | polyline={polyline} |
| | | style={{ width: "100%", height: "87vh" }} |
| | | > |
| | | {renderMapOverlays()} |
| | | {/* 顶部返回/首页按钮 */} |
| | | <View onClick={goHome} className="select-city"> |
| | | <Image className="select-city-icon" src={homeIcon} /> |
| | | </View> |
| | | <View className="container"> |
| | | {/* 提醒 */} |
| | | <View className="tip-box"> |
| | | <View className="tip-box-content"> |
| | | <View className="tip-box-text"> |
| | | 开启提醒后,亲友行程动态秒通知 |
| | | </View> |
| | | <View className="tip-box-btn">去开启</View> |
| | | </View> |
| | | {/* 联系客服悬浮按钮 */} |
| | | <View className={`share-contact ${showReminder ? "has-tip" : ""}`}> |
| | | <Image className="share-contact-icon" src={contactServiceIcon} /> |
| | | </View> |
| | | {/* 提醒 */} |
| | | {showReminder && ( |
| | | <View className="tip-box"> |
| | | <View className="tip-box-content"> |
| | | <View className="tip-box-text"> |
| | | 开启提醒后,亲友行程动态秒通知 |
| | | </View> |
| | | <View |
| | | className="tip-box-btn" |
| | | onClick={() => setShowReminder(false)} |
| | | > |
| | | 去开启 |
| | | </View> |
| | | </View> |
| | | </View> |
| | | )} |
| | | <View className="container-inner"> |
| | | <View catchMove onClick={e => e.stopPropagation()}> |
| | | <View className="calling-car"> |
| | |
| | | className="calling-car-bg" |
| | | src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/site-top-bg.png" |
| | | /> |
| | | <View className="calling-car-head"> |
| | | {tripData?.tripStatus === 4 && ( |
| | | <View className="calling-car-head-title"> |
| | | 车辆还有 |
| | | <View className="calling-car-head-title-eta">{`${tripData.etaMinutes}`}</View> |
| | | 分钟到达上车点 |
| | | </View> |
| | | )} |
| | | {tripData?.tripStatus === 6 && ( |
| | | <View className="calling-car-head-title"> |
| | | 乘客已上车,正在前往目的地 |
| | | </View> |
| | | )} |
| | | {tripData?.tripStatus === 7 && ( |
| | | <View className="calling-car-head-title">已到达目的地</View> |
| | | )} |
| | | </View> |
| | | <View className="car-card"> |
| | | <View className="car-card-detail"> |
| | | <View> |
| | |
| | | src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/vehicle-default.png" |
| | | /> |
| | | </View> |
| | | <View className="car-card-line"></View> |
| | | <View className="car-card-temp"> |
| | | <View className="car-card-temp-list"> |
| | | <Image className="car-card-temp-img" src={shareLine} /> |
| | | {/* 起点 */} |
| | | <View className="car-card-temp-row"> |
| | | <View className="car-card-temp-row-left"> |
| | | <View className="dot start"></View> |
| | | <View |
| | | className={`car-card-temp-title ${ |
| | | tripData?.tripStatus === 6 || |
| | | tripData?.tripStatus === 7 |
| | | ? "disabled-text" |
| | | : "" |
| | | }`} |
| | | > |
| | | 起点:{tripData?.startName} |
| | | </View> |
| | | </View> |
| | | {(tripData?.tripStatus === 6 || |
| | | tripData?.tripStatus === 7) && |
| | | tripData?.boardTime && ( |
| | | <View className="car-card-temp-time disabled-text"> |
| | | {tripData.boardTime} 上车 |
| | | </View> |
| | | )} |
| | | </View> |
| | | |
| | | {/* 终点 */} |
| | | <View |
| | | className="car-card-temp-row" |
| | | style={{ marginTop: "12px" }} |
| | | > |
| | | <View className="car-card-temp-row-left"> |
| | | <View className="dot end"></View> |
| | | <View |
| | | className={`car-card-temp-title ${ |
| | | tripData?.tripStatus === 7 ? "disabled-text" : "" |
| | | }`} |
| | | > |
| | | 终点:{tripData?.endName} |
| | | </View> |
| | | </View> |
| | | {tripData?.tripStatus === 7 && tripData?.arriveTime && ( |
| | | <View className="car-card-temp-time disabled-text"> |
| | | {tripData.arriveTime} 到达 |
| | | </View> |
| | | )} |
| | | </View> |
| | | </View> |
| | | </View> |
| | | </View> |
| | | </View> |
| | | </View> |
| | |
| | | setLoading(true); |
| | | try { |
| | | const res = await getCollectPoints({ |
| | | current: page, |
| | | size: 4, |
| | | pageNum: page, |
| | | pageSize: 4, |
| | | }); |
| | | if (res && res.records) { |
| | | setList(prev => page === 1 ? res.records : [...prev, ...res.records]); |