feat(robotaxi): 添加自定义字体并优化页面布局与交互
- 引入 Figtree 字体文件及样式定义
- 调整首页底部面板高度和占位元素尺寸
- 限制常见问题列表最多显示10条
- 优化发布路线页面的金额显示逻辑和字体应用
- 修复行程状态切换时的地图路线显示问题
- 改进取消订单后的状态清理和路线重算逻辑
| | |
| | | * 但是 H5 上内置组件样式可能会错乱,因此暂时不这样处理,有用到 flex 的地方都显式声明主轴方向即可 |
| | | */ |
| | | |
| | | @import './assets/fonts/font.less'; |
| | | |
| | | /* weapp */ |
| | | page { |
| | | height: 100%; |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .taro_page { |
| | | flex: 1; |
| | | } |
| | | |
| | | /*postcss-pxtransform rn eject disable*/ |
| | | |
| | | |
| | | /* common styles */ |
| | | .link-text { |
| | | color: #00AFF0; |
| | | } |
| | | } |
| New file |
| | |
| | | @font-face { |
| | | font-family: 'Figtree-Light'; |
| | | src: url('./Figtree-Light.ttf'); |
| | | font-weight: normal; |
| | | font-style: normal; |
| | | } |
| | | |
| | | @font-face { |
| | | font-family: 'Figtree-Regular'; |
| | | src: url('./Figtree-Regular.ttf'); |
| | | font-weight: normal; |
| | | font-style: normal; |
| | | } |
| | | |
| | | @font-face { |
| | | font-family: 'Figtree-SemiBold'; |
| | | src: url('./Figtree-SemiBold.ttf'); |
| | | font-weight: normal; |
| | | font-style: normal; |
| | | } |
| | |
| | | border-radius: 40px 40px 0 0; |
| | | |
| | | .content-box-top { |
| | | padding-bottom: 24px; |
| | | padding-bottom: 102px; |
| | | } |
| | | |
| | | .origin-box { |
| | |
| | | const [orderData, setOrderData] = useState<any>({}); // 订单数据 |
| | | const [isLogin, setIsLogin] = useState(false); // 是否登录 |
| | | |
| | | const [boxHeight, setBoxHeight] = useState<number>(320); // 活动区域高度 |
| | | const [boxHeight, setBoxHeight] = useState<number>(359); // 活动区域高度 |
| | | const startY = useRef(0); // 拖动开始时的Y坐标 |
| | | const startHeight = useRef(0); // 拖动开始时的高度 |
| | | const fullHeight = useRef(0); // 活动区域最大高度 |
| | |
| | | console.log('getSetting获取scope.userLocation授权状态', auth); |
| | | if (auth == undefined) { |
| | | getLocationInfo(); |
| | | skipCityChangeEffectRef.current = true; |
| | | return; |
| | | } |
| | | if (auth === false) { |
| | |
| | | const cityName = (city && typeof city === 'string' && city.length > 0) ? city : province; |
| | | const cityCode = convertAdcodeToCityCode(adcode, cityName, province); |
| | | getCityInfoWithId(cityCode, cityName).then(cityInfo => { |
| | | // skipCityChangeEffectRef.current = true; |
| | | skipCityChangeEffectRef.current = true; |
| | | setSelectedCity(cityInfo); |
| | | Taro.setStorageSync('selectedCity', cityInfo); |
| | | }); |
| | |
| | | query.select('.content-body').boundingClientRect(rect => { |
| | | if (rect) { |
| | | const contentHeight = rect.height; |
| | | const baseHeight = 320; |
| | | const baseHeight = 359; |
| | | fullHeight.current = Math.max(contentHeight, baseHeight); |
| | | minHeight.current = baseHeight; |
| | | setBoxHeight(baseHeight); |
| | | } else { |
| | | // 兜底逻辑 |
| | | minHeight.current = 320; |
| | | fullHeight.current = 320; |
| | | setBoxHeight(320); |
| | | minHeight.current = 359; |
| | | fullHeight.current = 359; |
| | | setBoxHeight(359); |
| | | } |
| | | }).exec(); |
| | | }, 500); |
| | |
| | | {/* 占位 */} |
| | | { |
| | | getShowDomFlag() && |
| | | <View style={{ height: '33px' }}></View> |
| | | <View style={{ height: '32px' }}></View> |
| | | } |
| | | {/* 游客模式展示同意协议 */} |
| | | { |
| | |
| | | } |
| | | |
| | | .money-num { |
| | | font-family: 'Figtree-Light'; |
| | | margin: 0 4px; |
| | | font-size: 48px; |
| | | font-weight: 600; |
| | |
| | | </View> |
| | | <View className="route-content"> |
| | | <View className="route-content-top"> |
| | | <View className="route-content-txt">预估等待{fareEstimate.waitingTime || 0}分钟</View> |
| | | <View className="route-content-txt">预估等待{fareEstimate.waitingTime || '-'}分钟</View> |
| | | <View className="route-content-top-money" onClick={() => toPriceDescription()} > |
| | | <Image className="tip-icon" src={tipDefaultIcon} /> |
| | | 预估 |
| | | <Text className="money-num">{fareEstimate.finalFare || 0}</Text> |
| | | <Text className="money-num">{fareEstimate.finalFareStr || '-'}</Text> |
| | | 元 |
| | | </View> |
| | | </View> |
| | | <View className="route-content-bottom"> |
| | | <View onClick={handleOpenPassengerNotice} className="route-content-bottom-left"> |
| | | <View>限乘{fareEstimate.maxPeopleNumber || 0}人</View> |
| | | <View>限乘{fareEstimate.maxPeopleNumber || '-'}人</View> |
| | | <Image className="tip-icon" src={tipBlueIcon} /> |
| | | <View>乘车须知</View> |
| | | </View> |
| | | <View className="route-content-bottom-right"> |
| | | {fareEstimate.discountAmount > 0 && <View className="discount-amount">已优惠{fareEstimate.discountAmount}元</View>} |
| | | <View className="original-fare">{fareEstimate.originalFare || 0}元</View> |
| | | <View className="original-fare">{fareEstimate.originalFare || '-'}元</View> |
| | | </View> |
| | | </View> |
| | | </View> |
| | |
| | | setPolyline([]); |
| | | } |
| | | if (payload?.showCancelPopup) { |
| | | Taro.removeStorageSync('orderId'); |
| | | setOrderId(''); |
| | | clearOrderTripStorage(); |
| | | setTripStatus(1); |
| | | updateWalkingRouteForStart(); |
| | | const s = Taro.getStorageSync('startSite'); |
| | | const e = Taro.getStorageSync('endSite'); |
| | | if (s?.latitude && s?.longitude && e?.longitude && e?.latitude) { |
| | | requestRouteAndFare(s.latitude, s.longitude, e.latitude, e.longitude, true); |
| | | } |
| | | } |
| | | if (payload?.showPassengerNotice) { |
| | | if (Taro.getStorageSync('passengerNoticeShowed') !== 'true') { |
| | |
| | | requoteTimer = setInterval(updateRequoteElapsed, 1000); |
| | | } else { |
| | | requoteTriggeredRef.current = false; |
| | | // 离开发布阶段后清空步行路线,避免在进行中/支付成功阶段仍显示步行线 |
| | | setWalkingPoints([]); |
| | | setWalkingTime(0); |
| | | } |
| | | // tripStatus=2/3:等待计时 |
| | | if (tripStatus == 2 || tripStatus == 3) { |
| | |
| | | if (includeDropoff && dropoffMarker) nextMarkers.push(dropoffMarker); |
| | | setMarkers(nextMarkers); |
| | | |
| | | if (shouldShowRoute && (routePoints.length > 0 || walkingPoints.length > 0)) { |
| | | if (shouldShowRoute && (routePoints.length > 0 || (tripStatus === 1 && walkingPoints.length > 0))) { |
| | | const lines: any[] = []; |
| | | if (routePoints.length > 0) { |
| | | lines.push({ |
| | |
| | | arrowLine: true, |
| | | }); |
| | | } |
| | | if (walkingPoints.length > 0) { |
| | | // 仅在发布行程阶段展示步行路线 |
| | | if (tripStatus === 1 && walkingPoints.length > 0) { |
| | | lines.push({ |
| | | points: walkingPoints, |
| | | color: '#7B91FF', |
| | |
| | | padding: [50, 50, 500, 50] |
| | | }); |
| | | } else { |
| | | const allPoints = [ |
| | | ...routePoints, |
| | | ...walkingPoints, |
| | | ]; |
| | | const allPoints = tripStatus === 1 |
| | | ? [...routePoints, ...walkingPoints] |
| | | : [...routePoints]; |
| | | mapCtx.includePoints({ |
| | | points: allPoints, |
| | | padding: [50, 50, ![1, 6].includes(tripStatus) ? 500 : 100, 50] |
| | |
| | | const fetchFAQ = async () => { |
| | | try { |
| | | const res = await getFAQList(); |
| | | setFaqData(res || []); |
| | | setFaqData(res.length > 10 ? res.slice(0, 10) : res || []); |
| | | } catch (error) { |
| | | console.error('获取常见问题失败', error); |
| | | } |