| src/app.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/robotaxi/home/hooks/use-navigation.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-all.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-arrow.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-back.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-bg.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-cancelled.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-finished.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-line.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/assets/mine-pay.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/personal-center/index.config.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/personal-center/index.less | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/robotaxi/pages/personal-center/index.tsx | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/app.config.ts
@@ -37,6 +37,7 @@ 'pages/agreement-page/index', 'pages/operating-area/index', 'pages/share-trip/index', 'pages/personal-center/index', ], }, { src/pages/robotaxi/home/hooks/use-navigation.ts
@@ -54,13 +54,12 @@ }; /** * 拨打客服。 * 打开个人中心。 */ const openService = async () => { const ok = await ensureNetwork(); if (!ok) return; const phoneNumber = Taro.getStorageSync('customerServicePhone'); Taro.makePhoneCall({ phoneNumber }); Taro.navigateTo({ url: '/robotaxi/pages/personal-center/index' }); }; /** src/robotaxi/assets/mine-all.png
src/robotaxi/assets/mine-arrow.png
src/robotaxi/assets/mine-back.png
src/robotaxi/assets/mine-bg.png
src/robotaxi/assets/mine-cancelled.png
src/robotaxi/assets/mine-finished.png
src/robotaxi/assets/mine-line.png
src/robotaxi/assets/mine-pay.png
src/robotaxi/pages/personal-center/index.config.ts
New file @@ -0,0 +1,5 @@ export default { navigationBarTitleText: '个人中心', navigationStyle: 'custom', disableScroll: false, } src/robotaxi/pages/personal-center/index.less
New file @@ -0,0 +1,163 @@ .personal-center-page { min-height: 100vh; box-sizing: border-box; background-image: url("../../assets/mine-bg.png"); background-size: 100% 804px; background-repeat: no-repeat; background-color: #f5f6fa; } .personal-center-header { padding: 108px 48px 0; display: flex; align-items: center; justify-content: space-between; .header-left { width: 48px; height: 48px; } .header-back-icon { width: 48px; height: 48px; } } .personal-center-content { padding: 52px 22px 0 24px; } .user-name { font-size: 36px; line-height: 48px; font-weight: 500; color: rgba(0, 0, 0, 0.9); margin-bottom: 48px; padding-left: 8px; } .coupon-card { height: 112px; border-radius: 16px; background: #fff5e5; box-sizing: border-box; border: 2px solid #ffffff; margin-bottom: 24px; display: flex; align-items: center; justify-content: space-between; padding: 0 24px 0 42px; .coupon-card-title { font-size: 28px; line-height: 44px; color: rgba(0, 0, 0, 0.9); } .coupon-card-right { display: flex; align-items: center; } .coupon-card-count { font-size: 28px; line-height: 44px; color: rgba(0, 0, 0, 0.4); margin-right: 8px; } .coupon-card-arrow { width: 32px; height: 32px; } } .section-card { background: #ffffff; border-radius: 24px; padding: 24px 0; margin-bottom: 24px; &:last-child { padding: 32px 0; padding-bottom: 8px; } } .section-title { font-size: 28px; font-weight: 600; line-height: 44px; /* 文字色/黑色/重要字 90% */ color: rgba(0, 0, 0, 0.9); text-indent: 32px; margin-bottom: 20px; } .section-card:last-child { .section-title { margin-bottom: 8px; } } .trip-menu { display: flex; align-items: center; padding-left: 8px; } .trip-menu-item { width: 172px; height: 120px; display: flex; flex-direction: column; align-items: center; position: relative; } .all { width: 134px; } .mine-line { position: absolute; left: 0; top: 0; width: 6px; height: 120px; } .trip-menu-icon { width: 80px; height: 80px; box-sizing: border-box; } .trip-menu-label { font-size: 24px; line-height: 40px; color: rgba(0, 0, 0, 0.9); } .tool-menu-item { height: 110px; display: flex; align-items: center; justify-content: space-between; padding-left: 32px; padding-right: 24px; transition: background-color 0.2s; } .tool-menu-item-hover { background-color: rgba(0, 0, 0, 0.05); } .tool-menu-label { font-size: 28px; line-height: 44px; color: rgba(0, 0, 0, 0.9); } .tool-menu-arrow { width: 32px; height: 32px; } src/robotaxi/pages/personal-center/index.tsx
New file @@ -0,0 +1,155 @@ import Taro from "@tarojs/taro"; import { View, Text, Image } from "@tarojs/components"; import { useState } from "react"; import backIcon from "../../assets/mine-back.png"; import mineArrow from "../../assets/mine-arrow.png"; import mineLine from "../../assets/mine-line.png"; import waitPay from "../../assets/mine-pay.png"; import finished from "../../assets/mine-finished.png"; import cancelled from "../../assets/mine-cancelled.png"; import all from "../../assets/mine-all.png"; import FavoritePopup from "../site-search/components/favorite-popup"; import "./index.less"; type TripMenuItem = { key: string; label: string; count?: string; icon: string; }; type ToolMenuItem = { key: string; label: string; }; const tripMenuList: TripMenuItem[] = [ { key: "pending", label: "待支付", icon: waitPay }, { key: "finished", label: "已完成", icon: finished }, { key: "cancelled", label: "已取消", icon: cancelled }, { key: "all", label: "全部订单", icon: all } ]; const toolMenuList: ToolMenuItem[] = [ { key: "service", label: "联系客服" }, { key: "invoice", label: "开发票" }, { key: "payment", label: "支付设置" }, { key: "favorite", label: "收藏站点" } ]; export default function PersonalCenter() { const nickname = Taro.getStorageSync("nickname") || "小鹏艺术家小鹏艺"; const [showFavoritePopup, setShowFavoritePopup] = useState(false); const handleBack = () => { Taro.navigateBack({ fail: () => Taro.reLaunch({ url: "/pages/robotaxi/home/index" }) }); }; const handleTripClick = (key: string) => { if ( key === "all" || key === "pending" || key === "finished" || key === "cancelled" ) { Taro.navigateTo({ url: "/robotaxi/pages/order/index" }); } }; const handleToolClick = (key: string) => { if (key === "service") { const phoneNumber = Taro.getStorageSync("customerServicePhone"); if (phoneNumber) { Taro.makePhoneCall({ phoneNumber }); } else { Taro.showToast({ title: "暂无客服电话", icon: "none" }); } return; } if (key === "favorite") { setShowFavoritePopup(true); return; } Taro.showToast({ title: "功能建设中", icon: "none" }); }; return ( <View className="personal-center-page"> <View className="personal-center-container"> <View className="personal-center-header"> <View className="header-left" onClick={handleBack}> <Image className="header-back-icon" src={backIcon} /> </View> </View> <View className="personal-center-content"> <View className="user-name">{nickname}</View> <View className="coupon-card" onClick={() => Taro.navigateTo({ url: "/robotaxi/pages/coupon/index" }) } > <Text className="coupon-card-title">我的优惠券</Text> <View className="coupon-card-right"> <Text className="coupon-card-count">5张</Text> <Image className="coupon-card-arrow" src={mineArrow} /> </View> </View> <View className="section-card"> <View className="section-title">我的行程</View> <View className="trip-menu"> {tripMenuList.map(item => ( <View key={item.key} className={item.key === "all" ? "trip-menu-item all" : "trip-menu-item"} onClick={() => handleTripClick(item.key)} > {item.key === "all" && ( <Image className="mine-line" src={mineLine} /> )} <Image className="trip-menu-icon" src={item.icon} /> <Text className="trip-menu-label">{item.label}</Text> </View> ))} </View> </View> <View className="section-card"> <View className="section-title">服务与工具</View> <View className="tool-menu"> {toolMenuList.map(item => ( <View key={item.key} className="tool-menu-item" hoverClass="tool-menu-item-hover" onClick={() => handleToolClick(item.key)} > <Text className="tool-menu-label">{item.label}</Text> <Image className="tool-menu-arrow" src={mineArrow} /> </View> ))} </View> </View> </View> </View> <FavoritePopup show={showFavoritePopup} onClose={() => setShowFavoritePopup(false)} onSelect={(item) => { console.log('Selected favorite item:', item); // TODO: handle favorite item selection }} /> </View> ); }