| | |
| | | import { View, Text, Image, Swiper, SwiperItem } from '@tarojs/components'; |
| | | import OrderStatusCard from './order-status-card'; |
| | | import { TripStatus } from '../../../../robotaxi/constants/trip-status'; |
| | | import { safeParse } from '../../../../utils/Robotaxi-public-method'; |
| | | |
| | | type Props = { |
| | |
| | | boxHeight: number; |
| | | /** 是否拖拽中。 */ |
| | | isDragging: boolean; |
| | | /** 是否展示订单状态卡片。 */ |
| | | shouldShowOrderStatusCard: boolean; |
| | | /** 当前行程状态。 */ |
| | | tripStatus: TripStatus | 0; |
| | | /** 当前订单数据。 */ |
| | | orderData: any; |
| | | /** 订单状态文案映射。 */ |
| | | orderStatusMap: Partial<Record<TripStatus, string>>; |
| | | /** 当前是否在运营区。 */ |
| | | isOperatingArea: boolean; |
| | | /** 当前是否吸附站点。 */ |
| | |
| | | onSelectSite: (type: string) => void; |
| | | /** 快捷胶囊点击。 */ |
| | | onQuickCapsuleClick: () => void; |
| | | /** 查看订单详情。 */ |
| | | onViewOrderDetail: () => void; |
| | | /** Banner 点击。 */ |
| | | onBannerClick: (item: any) => void; |
| | | /** 打开协议页。 */ |
| | |
| | | </View> |
| | | </View> |
| | | </View> |
| | | {props.shouldShowOrderStatusCard && ( |
| | | <OrderStatusCard |
| | | tripStatus={props.tripStatus} |
| | | orderData={props.orderData} |
| | | onViewDetail={props.onViewOrderDetail} |
| | | orderStatusMap={props.orderStatusMap} |
| | | /> |
| | | )} |
| | | |
| | | {props.bannerList.length > 0 && ( |
| | | {props.bannerList.length > 0 && ( |
| | | <View className="activity"> |
| | | <Swiper |
| | | className="activity-swiper" |
| | |
| | | import MapOverlayTips from './map-overlay-tips'; |
| | | import MapPointer from './map-pointer'; |
| | | import CitySelect from './city-select'; |
| | | import OrderStatusCard from './order-status-card'; |
| | | import { getWeatherIconByDesc } from '../../../../utils/weather'; |
| | | import { DEFAULT_LATITUDE, DEFAULT_LONGITUDE } from '../../../../robotaxi/constants/map'; |
| | | import { HOME_MAP_HEIGHT, HOME_MAP_ID } from '../constants'; |
| | | import { TripStatus } from '../../../../robotaxi/constants/trip-status'; |
| | | |
| | | type Props = { |
| | | /** 地图经度。 */ |
| | |
| | | isAdsorbed: boolean; |
| | | /** 当前站点。 */ |
| | | currentSite: any; |
| | | /** 是否展示订单状态卡片。 */ |
| | | shouldShowOrderStatusCard: boolean; |
| | | /** 当前行程状态。 */ |
| | | tripStatus: TripStatus | 0; |
| | | /** 当前订单数据。 */ |
| | | orderData: any; |
| | | /** 订单状态文案映射。 */ |
| | | orderStatusMap: Partial<Record<TripStatus, string>>; |
| | | /** 等待态雷达资源。 */ |
| | | waitingRadarSrc: string; |
| | | /** 地图区域变化回调。 */ |
| | |
| | | onToCoupon: () => void; |
| | | /** 选择站点。 */ |
| | | onSelectSite: (type: string) => void; |
| | | /** 查看订单详情。 */ |
| | | onViewOrderDetail: () => void; |
| | | }; |
| | | |
| | | /** |
| | |
| | | bottom: typeof props.overlayAnchorBottom === 'number' ? `${props.overlayAnchorBottom}px` : undefined |
| | | }} |
| | | > |
| | | <Image onClick={props.onToOrigin} className="origin-icon" src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/origin-icon-20260716.png' /> |
| | | <View className='origin-box-container'> |
| | | <Image onClick={props.onToOrigin} className="origin-icon" src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/origin-icon-20260716.png' /> |
| | | {props.shouldShowOrderStatusCard && ( |
| | | <View className="order-status-overlay"> |
| | | <OrderStatusCard |
| | | tripStatus={props.tripStatus} |
| | | orderData={props.orderData} |
| | | onViewDetail={props.onViewOrderDetail} |
| | | orderStatusMap={props.orderStatusMap} |
| | | /> |
| | | </View> |
| | | )} |
| | | </View> |
| | | </View> |
| | | <MapOverlayTips |
| | | isGuest={props.shouldShowGuestTip} |
| | |
| | | onShowPrivacy={props.onShowPrivacy} |
| | | onOpenSetting={props.onOpenSetting} |
| | | onViewOperatingArea={props.onViewOperatingArea} |
| | | shouldShowOrderStatusCard={props.shouldShowOrderStatusCard} |
| | | /> |
| | | <View className="map-entry"> |
| | | <View className="map-entry-box"> |
| | |
| | | opacity?: number; |
| | | /** 拖拽状态,用于控制过渡动画 */ |
| | | isDragging?: boolean; |
| | | shouldShowOrderStatusCard: boolean; |
| | | }; |
| | | |
| | | /** |
| | |
| | | */ |
| | | export default function MapOverlayTips(props: Props) { |
| | | const anchorStyle = typeof props.anchorBottom === 'number' |
| | | ? { |
| | | top: 'auto', |
| | | ? { |
| | | top: 'auto', |
| | | bottom: `${props.anchorBottom}px`, |
| | | opacity: props.opacity !== undefined ? props.opacity : 1, |
| | | visibility: props.opacity !== undefined && props.opacity <= 0 ? 'hidden' : 'visible' as any, |
| | |
| | | props.isMaintain && <View className={`is-maintain ml-32 ${props.maintainBounce ? 'maintain-bounce' : ''}`}>系统维护中,预计{props.hotfixEndText || '-:-'}恢复服务</View> |
| | | } |
| | | { |
| | | !props.isOperatingArea && <View onClick={props.onViewOperatingArea} className="is-operating-area mt-20">查看运营区域</View> |
| | | !props.isOperatingArea && !props.shouldShowOrderStatusCard && <View onClick={props.onViewOperatingArea} className="is-operating-area mt-20">查看运营区域</View> |
| | | } |
| | | </View> |
| | | </View> |
| | |
| | | { |
| | | [TripStatus.CallingCar].includes(tripStatus as TripStatus) && |
| | | <View className="order-status-left"> |
| | | <View className="order-status-left-item"> |
| | | <Image className="order-status-left-item-icon" src="https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/pointer.png" /> |
| | | <View></View> |
| | | <View></View> |
| | | </View> |
| | | <View className="order-status-left-text">正在为您呼叫...</View> |
| | | </View> |
| | | } |
| | |
| | | </View> |
| | | } |
| | | <View onClick={onViewDetail} className="order-status-btn">查看</View> |
| | | <Image className="order-status-bg" src={'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/order-card-bg.png'} /> |
| | | </View> |
| | | ); |
| | | } |
| | |
| | | .origin-box { |
| | | position: fixed; |
| | | top: 55%; |
| | | left: 24px; |
| | | right: 24px; |
| | | z-index: 3; |
| | | .origin-box-container { |
| | | width: 100%; |
| | | display: flex; |
| | | align-items: flex-end; |
| | | justify-content: flex-end; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .origin-icon { |
| | | width: 80px; |
| | | height: 80px; |
| | | } |
| | | } |
| | | |
| | | .order-status-overlay { |
| | | width: 100%; |
| | | flex-shrink: 0; |
| | | margin-top: 24px; |
| | | .order-status { |
| | | position: relative; |
| | | border-radius: 24px; |
| | | background-color: #141E27; |
| | | background-image: url("https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/order-card-homepage-20260724.png"); |
| | | background-size: cover; |
| | | box-sizing: border-box; |
| | | height: 116px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding-right: 32px; |
| | | padding-left: 28px; |
| | | |
| | | .order-status-left { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .order-status-left-item { |
| | | margin-right: 12px; |
| | | position: relative; |
| | | margin-left: 14px; |
| | | display: flex; |
| | | justify-content: center; |
| | | width: 78px; |
| | | height: 78px; |
| | | |
| | | view { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | border-radius: 50%; |
| | | width: 78px; |
| | | height: 78px; |
| | | background: rgba(64, 124, 255, 0.2); |
| | | animation: radiate 2s infinite ease-out; |
| | | } |
| | | |
| | | view:last-child { |
| | | animation-delay: 1s; |
| | | } |
| | | |
| | | &-icon { |
| | | position: relative; |
| | | z-index: 9; |
| | | width: 26px; |
| | | height: 38px; |
| | | } |
| | | } |
| | | |
| | | .order-status-left-text { |
| | | font-family: PingFang SC; |
| | | font-size: 28px; |
| | | font-weight: 500; |
| | | letter-spacing: normal; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .order-status-left-icon { |
| | | width: 136px; |
| | | height: 116.9px; |
| | | margin-top: 16px; |
| | | flex-shrink: 0; |
| | | object-fit: contain; |
| | | } |
| | | |
| | | .order-status-left-detail { |
| | | margin-left: 16px; |
| | | |
| | | view:first-child { |
| | | font-size: 24px; |
| | | letter-spacing: normal; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | view:last-child { |
| | | margin-top: 12px; |
| | | font-size: 28px; |
| | | letter-spacing: normal; |
| | | font-weight: 500; |
| | | color: #FFFFFF; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-btn { |
| | | position: relative; |
| | | z-index: 1; |
| | | line-height: 40px; |
| | | padding: 8px 32px; |
| | | font-size: 24px; |
| | | font-weight: 500; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | border-radius: 200px; |
| | | background: #ECF0F5; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | 100% { |
| | | transform: translate(-50%, -50%) scale(1.2); |
| | | opacity: 0; |
| | | } |
| | | } |
| | | |
| | | .order-status { |
| | | position: relative; |
| | | margin-top: 24px; |
| | | margin-bottom: 6px; |
| | | border-radius: 24px; |
| | | background: #fefefe; |
| | | box-sizing: border-box; |
| | | border: 0px solid #ffffff; |
| | | height: 104px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding-right: 24px; |
| | | |
| | | &-left { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &-item { |
| | | margin-right: 12px; |
| | | position: relative; |
| | | margin-left: 14px; |
| | | display: flex; |
| | | justify-content: center; |
| | | width: 78px; |
| | | height: 78px; |
| | | |
| | | view { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | border-radius: 50%; |
| | | width: 78px; |
| | | height: 78px; |
| | | background: rgba(64, 124, 255, 0.2); |
| | | animation: radiate 2s infinite ease-out; |
| | | } |
| | | |
| | | view:last-child { |
| | | animation-delay: 1s; |
| | | } |
| | | |
| | | &-icon { |
| | | position: relative; |
| | | z-index: 9; |
| | | width: 26px; |
| | | height: 38px; |
| | | } |
| | | } |
| | | |
| | | &-text { |
| | | font-family: PingFang SC; |
| | | font-size: 28px; |
| | | font-weight: 500; |
| | | line-height: 48px; |
| | | letter-spacing: normal; |
| | | color: #3d3d3d; |
| | | } |
| | | |
| | | &-icon { |
| | | width: 156px; |
| | | height: 73.54px; |
| | | margin-left: 18px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | &-detail { |
| | | margin-left: 16px; |
| | | |
| | | view:first-child { |
| | | font-size: 28px; |
| | | line-height: 44px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.9); |
| | | } |
| | | |
| | | view:last-child { |
| | | font-size: 20px; |
| | | line-height: 20px; |
| | | letter-spacing: normal; |
| | | color: rgba(0, 0, 0, 0.4); |
| | | } |
| | | } |
| | | } |
| | | |
| | | &-btn { |
| | | position: relative; |
| | | z-index: 1; |
| | | line-height: 56px; |
| | | padding: 0 28px; |
| | | font-size: 24px; |
| | | letter-spacing: normal; |
| | | color: #ffffff; |
| | | border-radius: 200px; |
| | | background: linear-gradient(111deg, #8475ff 0%, #7dd6ff 98%); |
| | | } |
| | | |
| | | &-bg { |
| | | position: absolute; |
| | | top: 4px; |
| | | right: 4px; |
| | | width: 266px; |
| | | height: 96px; |
| | | } |
| | | } |
| | | |
| | |
| | | bounce={bounce} |
| | | isAdsorbed={isAdsorbed} |
| | | currentSite={currentSite} |
| | | shouldShowOrderStatusCard={shouldShowOrderStatusCard} |
| | | tripStatus={tripStatus} |
| | | orderData={orderData} |
| | | orderStatusMap={HOME_ORDER_STATUS} |
| | | waitingRadarSrc={WAITING_RADAR_SRC} |
| | | onRegionChange={handleRegionChange} |
| | | onMarkerTap={handleMarkerTap} |
| | |
| | | onOpenService={openService} |
| | | onToCoupon={toCoupon} |
| | | onSelectSite={toSelectSitePage} |
| | | onViewOrderDetail={toOrderDetail} |
| | | /> |
| | | <HomeContentPanel |
| | | bannerList={bannerList} |
| | | boxHeight={boxHeight} |
| | | isDragging={isDragging.current} |
| | | shouldShowOrderStatusCard={shouldShowOrderStatusCard} |
| | | tripStatus={tripStatus} |
| | | orderData={orderData} |
| | | orderStatusMap={HOME_ORDER_STATUS} |
| | | isOperatingArea={isOperatingArea} |
| | | isAdsorbed={isAdsorbed} |
| | | currentSite={currentSite} |
| | |
| | | quickCapsuleText={quickCapsuleText} |
| | | onSelectSite={toSelectSitePage} |
| | | onQuickCapsuleClick={handleQuickCapsuleClick} |
| | | onViewOrderDetail={toOrderDetail} |
| | | onBannerClick={handleBannerClick} |
| | | onToAgreement={toAgreementPage} |
| | | onTouchStart={handleTouchStart} |
| | |
| | | if (!Number.isFinite(discountAmount) || discountAmount <= 0) { |
| | | return '0元'; |
| | | } |
| | | return `-${parseFloat(discountAmount.toFixed(2))}元`; |
| | | return `${parseFloat(discountAmount.toFixed(2))}元`; |
| | | }; |
| | | |
| | | useEffect(() => { |
| | |
| | | <View className="discount-amount-desc" >已为您选择最佳优惠</View> |
| | | </View> |
| | | <View className="flex-center"> |
| | | <View className="discount-amount-num">{formatDiscountAmountText()}</View> |
| | | <View className="discount-amount-num">-{formatDiscountAmountText()}</View> |
| | | <Image className="change-coupon-icon" src='https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/v2/golden-arrow-20260702.png' /> |
| | | </View> |
| | | </View> |