结尾有示例图

到家服务流程设计

选择城市

用户进入应用或网站后,需选择服务所在城市。通常通过定位自动获取当前城市,也可手动切换。城市选择影响后续服务人员及价格的展示。

服务人员列表

根据所选城市,展示可提供服务的人员列表。列表通常包含人员头像、评分、服务次数、距离、价格等信息。支持按评分、距离、价格等条件筛选排序。

服务详情页

点击具体服务人员后,进入详情页。展示更详细的信息,如个人简介、服务项目、用户评价、服务范围等。部分平台会展示服务人员的资质证明或案例照片。

预约时间

用户选择服务日期和时间段。系统会显示服务人员的可预约时段,避免冲突。部分服务需提前预约,如家政、维修等。

支付页面

确认服务信息后,进入支付页面。支持多种支付方式,如微信、支付宝、银行卡等。支付完成后生成订单,部分服务支持预约后支付或到付。

优化建议

  • 城市切换流畅性:确保定位准确,手动切换城市时无延迟。
  • 服务人员展示:增加标签(如“金牌”、“新人”),帮助用户快速决策。
  • 预约时间灵活性:提供非工作时间预约选项,满足特殊需求。
  • 支付安全:明确显示支付金额,避免隐藏费用,提供订单取消和退款说明。

通过以上步骤,可提升用户体验并提高订单转化率。


<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>到家服务平台</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  
  <!-- 配置Tailwind -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#165DFF',
            secondary: '#FF7D00',
            neutral: '#F5F7FA',
            dark: '#1D2129',
            light: '#86909C'
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>
  
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .card-shadow {
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
      }
      .transition-custom {
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }
      .page-enter {
        opacity: 0;
        transform: translateY(10px);
      }
      .page-enter-active {
        opacity: 1;
        transform: translateY(0);
      }
    }
  </style>
</head>
<body class="font-inter bg-neutral text-dark min-h-screen">
  <!-- 页面容器 -->
  <div id="app" class="max-w-6xl mx-auto bg-white min-h-screen relative overflow-hidden">
    <!-- 导航栏 -->
    <header class="sticky top-0 z-50 bg-white/90 backdrop-blur-sm border-b border-gray-100 shadow-sm">
      <div class="container mx-auto px-4 py-3 flex justify-between items-center">
        <div class="flex items-center space-x-1">
          <i class="fa fa-home text-primary text-xl"></i>
          <h1 class="text-lg font-bold text-primary">到家服务</h1>
        </div>
        <div class="flex items-center space-x-4">
          <button id="backBtn" class="text-light hover:text-primary transition-custom hidden">
            <i class="fa fa-arrow-left"></i>
          </button>
          <button id="userBtn" class="text-light hover:text-primary transition-custom">
            <i class="fa fa-user-circle-o text-xl"></i>
          </button>
        </div>
      </div>
    </header>

    <!-- 主内容区 -->
    <main class="min-h-[calc(100vh-100px)]">
      <!-- 1. 城市选择页面 -->
      <section id="cityPage" class="page py-6 px-4">
        <div class="mb-6">
          <h2 class="text-[clamp(1.25rem,3vw,1.75rem)] font-bold mb-2">选择城市</h2>
          <p class="text-light">请选择您所在的城市,以便为您提供精准服务</p>
        </div>
        
        <!-- 搜索框 -->
        <div class="relative mb-6">
          <i class="fa fa-search absolute left-3 top-1/2 -translate-y-1/2 text-light"></i>
          <input 
            type="text" 
            id="citySearch" 
            placeholder="搜索城市..." 
            class="w-full pl-10 pr-4 py-3 rounded-lg border border-gray-200 focus:border-primary focus:ring-1 focus:ring-primary outline-none transition-custom"
          >
        </div>
        
        <!-- 热门城市 -->
        <div class="mb-8">
          <h3 class="text-sm font-semibold text-light uppercase mb-3">热门城市</h3>
          <div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-3" id="hotCities">
            <!-- 城市将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 所有城市 -->
        <div>
          <h3 class="text-sm font-semibold text-light uppercase mb-3">所有城市</h3>
          <div id="allCities" class="space-y-4">
            <!-- 城市列表将通过JS动态生成 -->
          </div>
        </div>
      </section>

      <!-- 2. 服务人员列表页面 -->
      <section id="serviceListPage" class="page py-6 px-4 hidden">
        <div class="mb-6">
          <h2 class="text-[clamp(1.25rem,3vw,1.75rem)] font-bold mb-2">服务人员</h2>
          <p class="text-light" id="currentCityText">当前城市:北京市</p>
        </div>
        
        <!-- 筛选器 -->
        <div class="flex overflow-x-auto pb-2 mb-6 space-x-3 hide-scrollbar">
          <button class="whitespace-nowrap px-4 py-2 bg-primary text-white rounded-full text-sm">全部服务</button>
          <button class="whitespace-nowrap px-4 py-2 bg-white border border-gray-200 hover:border-primary rounded-full text-sm transition-custom">保洁服务</button>
          <button class="whitespace-nowrap px-4 py-2 bg-white border border-gray-200 hover:border-primary rounded-full text-sm transition-custom">家电维修</button>
          <button class="whitespace-nowrap px-4 py-2 bg-white border border-gray-200 hover:border-primary rounded-full text-sm transition-custom">管道疏通</button>
          <button class="whitespace-nowrap px-4 py-2 bg-white border border-gray-200 hover:border-primary rounded-full text-sm transition-custom">开锁换锁</button>
          <button class="whitespace-nowrap px-4 py-2 bg-white border border-gray-200 hover:border-primary rounded-full text-sm transition-custom">搬家服务</button>
        </div>
        
        <!-- 服务人员列表 -->
        <div id="serviceWorkersList" class="space-y-5">
          <!-- 服务人员卡片将通过JS动态生成 -->
        </div>
      </section>

      <!-- 3. 服务人员详情页面 -->
      <section id="serviceDetailPage" class="page py-6 px-4 hidden">
        <div class="mb-6">
          <h2 class="text-[clamp(1.25rem,3vw,1.75rem)] font-bold">服务详情</h2>
        </div>
        
        <!-- 服务人员信息 -->
        <div class="bg-neutral rounded-xl p-5 mb-6">
          <div class="flex items-start space-x-4">
            <img id="detailAvatar" src="" alt="服务人员头像" class="w-20 h-20 rounded-full object-cover">
            <div class="flex-1">
              <div class="flex justify-between items-start">
                <div>
                  <h3 id="detailName" class="text-xl font-bold"></h3>
                  <p id="detailServiceType" class="text-light"></p>
                </div>
                <div class="bg-primary/10 text-primary px-3 py-1 rounded-full text-sm font-medium">
                  <i class="fa fa-star mr-1"></i><span id="detailRating"></span>
                </div>
              </div>
              
              <div class="flex flex-wrap gap-2 mt-3">
                <span class="bg-white px-3 py-1 rounded-full text-sm border border-gray-200">
                  <i class="fa fa-clock-o mr-1 text-light"></i><span id="detailExperience"></span>
                </span>
                <span class="bg-white px-3 py-1 rounded-full text-sm border border-gray-200">
                  <i class="fa fa-map-marker mr-1 text-light"></i><span id="detailDistance"></span>
                </span>
                <span class="bg-white px-3 py-1 rounded-full text-sm border border-gray-200">
                  <i class="fa fa-check-circle mr-1 text-light"></i><span id="detailVerified"></span>
                </span>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 服务介绍 -->
        <div class="mb-6">
          <h3 class="text-lg font-bold mb-3">服务介绍</h3>
          <div class="bg-white rounded-xl p-5 border border-gray-100" id="detailDescription">
            <!-- 服务介绍将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 服务价格 -->
        <div class="mb-6">
          <h3 class="text-lg font-bold mb-3">服务价格</h3>
          <div class="bg-white rounded-xl p-5 border border-gray-100 space-y-3" id="detailPricing">
            <!-- 价格信息将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 客户评价 -->
        <div class="mb-6">
          <h3 class="text-lg font-bold mb-3">客户评价</h3>
          <div id="detailReviews" class="space-y-4">
            <!-- 评价信息将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 底部预约按钮 -->
        <div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 max-w-6xl mx-auto">
          <button id="bookServiceBtn" class="w-full bg-secondary hover:bg-secondary/90 text-white font-medium py-3 rounded-lg transition-custom flex justify-center items-center">
            <span>立即预约</span>
            <i class="fa fa-arrow-right ml-2"></i>
          </button>
        </div>
      </section>

      <!-- 4. 预约时间页面 -->
      <section id="bookingTimePage" class="page py-6 px-4 hidden">
        <div class="mb-6">
          <h2 class="text-[clamp(1.25rem,3vw,1.75rem)] font-bold">选择预约时间</h2>
          <p class="text-light">请选择您方便的服务时间</p>
        </div>
        
        <!-- 服务人员简要信息 -->
        <div class="bg-neutral rounded-xl p-4 mb-6 flex items-center space-x-3">
          <img id="bookingAvatar" src="" alt="服务人员头像" class="w-14 h-14 rounded-full object-cover">
          <div>
            <h3 id="bookingName" class="font-medium"></h3>
            <p id="bookingServiceType" class="text-sm text-light"></p>
          </div>
        </div>
        
        <!-- 日期选择 -->
        <div class="mb-6">
          <h3 class="text-lg font-bold mb-3">选择日期</h3>
          <div class="grid grid-cols-3 sm:grid-cols-5 gap-3" id="dateSelector">
            <!-- 日期将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 时间段选择 -->
        <div class="mb-16">
          <h3 class="text-lg font-bold mb-3">选择时间段</h3>
          <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3" id="timeSlots">
            <!-- 时间段将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 底部确认按钮 -->
        <div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 max-w-6xl mx-auto">
          <button id="confirmTimeBtn" class="w-full bg-primary hover:bg-primary/90 text-white font-medium py-3 rounded-lg transition-custom flex justify-center items-center">
            <span>确认时间并支付</span>
            <i class="fa fa-arrow-right ml-2"></i>
          </button>
        </div>
      </section>

      <!-- 5. 支付页面 -->
      <section id="paymentPage" class="page py-6 px-4 hidden">
        <div class="mb-6">
          <h2 class="text-[clamp(1.25rem,3vw,1.75rem)] font-bold">确认支付</h2>
          <p class="text-light">请确认订单信息并完成支付</p>
        </div>
        
        <!-- 订单信息 -->
        <div class="bg-white rounded-xl p-5 mb-6 border border-gray-100">
          <h3 class="font-bold mb-4">订单信息</h3>
          
          <div class="flex items-center space-x-3 mb-4">
            <img id="paymentAvatar" src="" alt="服务人员头像" class="w-12 h-12 rounded-full object-cover">
            <div>
              <h4 id="paymentName" class="font-medium"></h4>
              <p id="paymentServiceType" class="text-sm text-light"></p>
            </div>
          </div>
          
          <div class="space-y-3 text-sm">
            <div class="flex justify-between">
              <span class="text-light">服务城市</span>
              <span id="paymentCity"></span>
            </div>
            <div class="flex justify-between">
              <span class="text-light">服务时间</span>
              <span id="paymentDateTime"></span>
            </div>
            <div class="flex justify-between">
              <span class="text-light">服务项目</span>
              <span id="paymentServiceItem"></span>
            </div>
          </div>
        </div>
        
        <!-- 支付方式 -->
        <div class="bg-white rounded-xl p-5 mb-6 border border-gray-100">
          <h3 class="font-bold mb-4">选择支付方式</h3>
          <div class="space-y-3" id="paymentMethods">
            <!-- 支付方式将通过JS动态生成 -->
          </div>
        </div>
        
        <!-- 价格信息 -->
        <div class="bg-white rounded-xl p-5 mb-16 border border-gray-100">
          <div class="space-y-3 text-sm mb-4">
            <div class="flex justify-between">
              <span class="text-light">服务费用</span>
              <span id="paymentAmount"></span>
            </div>
            <div class="flex justify-between">
              <span class="text-light">服务费</span>
              <span>¥20.00</span>
            </div>
            <div class="flex justify-between">
              <span class="text-light">优惠券</span>
              <span class="text-green-500">-¥10.00</span>
            </div>
          </div>
          
          <div class="pt-4 border-t border-gray-100 flex justify-between font-bold">
            <span>总计</span>
            <span id="totalPayment" class="text-xl"></span>
          </div>
        </div>
        
        <!-- 底部支付按钮 -->
        <div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 max-w-6xl mx-auto">
          <button id="completePaymentBtn" class="w-full bg-secondary hover:bg-secondary/90 text-white font-medium py-3 rounded-lg transition-custom flex justify-center items-center">
            <span>确认支付</span>
            <i class="fa fa-check ml-2"></i>
          </button>
        </div>
      </section>

      <!-- 支付成功页面 -->
      <section id="successPage" class="page py-6 px-4 hidden flex flex-col items-center justify-center min-h-[calc(100vh-100px)]">
        <div class="text-center max-w-md mx-auto">
          <div class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6">
            <i class="fa fa-check text-3xl text-green-500"></i>
          </div>
          <h2 class="text-2xl font-bold mb-2">预约成功!</h2>
          <p class="text-light mb-8">您的服务已预约成功,服务人员将按约定时间上门</p>
          
          <div class="bg-white rounded-xl p-5 border border-gray-100 mb-6 text-left">
            <div class="flex justify-between mb-3">
              <span class="text-light">订单编号</span>
              <span id="orderNumber" class="font-medium"></span>
            </div>
            <div class="flex justify-between mb-3">
              <span class="text-light">服务时间</span>
              <span id="orderDateTime" class="font-medium"></span>
            </div>
            <div class="flex justify-between">
              <span class="text-light">服务人员</span>
              <span id="orderWorkerName" class="font-medium"></span>
            </div>
          </div>
          
          <button id="backToHomeBtn" class="w-full bg-primary hover:bg-primary/90 text-white font-medium py-3 rounded-lg transition-custom">
            返回首页
          </button>
        </div>
      </section>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-100 py-4 text-center text-light text-sm">
      <p>© 到家服务平台 版权所有</p>
    </footer>
  </div>

  <script>
    // 模拟数据 - 城市数据
    const cityData = {
      hotCities: ["北京", "上海", "广州", "深圳", "杭州", "成都", "武汉", "南京"],
      allCities: [
        { letter: "A", cities: ["安庆", "安阳", "鞍山"] },
        { letter: "B", cities: ["北京", "保定", "包头", "滨州", "本溪"] },
        { letter: "C", cities: ["成都", "重庆", "长沙", "长春", "沧州"] },
        { letter: "D", cities: ["大连", "东莞", "德州", "丹东"] },
        { letter: "F", cities: ["福州", "佛山", "抚顺"] },
        { letter: "G", cities: ["广州", "贵阳", "桂林", "赣州"] },
        { letter: "H", cities: ["杭州", "哈尔滨", "合肥", "海口", "邯郸"] },
        { letter: "J", cities: ["济南", "南京", "吉林", "嘉兴", "江门"] },
        { letter: "S", cities: ["上海", "深圳", "沈阳", "石家庄", "苏州"] },
        { letter: "W", cities: ["武汉", "无锡", "温州", "潍坊"] },
        { letter: "X", cities: ["西安", "厦门", "徐州", "邢台"] },
        { letter: "Z", cities: ["郑州", "珠海", "淄博", "中山"] }
      ]
    };

    // 模拟数据 - 服务人员数据
    const serviceWorkersData = [
      {
        id: 1,
        name: "张师傅",
        avatar: "https://picsum.photos/id/1012/200/200",
        serviceType: "全能保洁",
        rating: 4.9,
        reviews: 128,
        experience: "5年经验",
        distance: "2.3公里",
        verified: "已认证",
        description: "专业保洁服务,擅长家庭日常保洁、深度清洁、厨房油污清洁、卫生间清洁等。自带全套清洁工具和环保清洁剂,保证清洁效果的同时呵护您的家人健康。",
        pricing: [
          { item: "日常保洁(2小时)", price: "¥120.00" },
          { item: "深度保洁(4小时)", price: "¥230.00" },
          { item: "全屋清洁(6小时)", price: "¥320.00" }
        ],
        reviews: [
          { name: "李女士", avatar: "https://picsum.photos/id/1027/100/100", rating: 5, content: "张师傅非常专业,打扫得很干净,特别是厨房油污处理得很彻底,非常满意!" },
          { name: "王先生", avatar: "https://picsum.photos/id/1025/100/100", rating: 4, content: "服务很到位,提前联系确认,清洁工具齐全,值得推荐。" }
        ],
        availableTimes: {
          "今天": ["09:00-11:00", "14:00-16:00", "16:00-18:00"],
          "明天": ["08:00-10:00", "10:00-12:00", "13:00-15:00", "15:00-17:00"],
          "后天": ["09:00-11:00", "11:00-13:00", "14:00-16:00", "16:00-18:00", "19:00-21:00"]
        }
      },
      {
        id: 2,
        name: "王师傅",
        avatar: "https://picsum.photos/id/1025/200/200",
        serviceType: "家电维修",
        rating: 4.8,
        reviews: 96,
        experience: "8年经验",
        distance: "3.5公里",
        verified: "已认证",
        description: "专业家电维修师傅,精通冰箱、空调、洗衣机、电视等各类家电维修。快速诊断故障,合理收费,提供三个月质保服务,让您无后顾之忧。",
        pricing: [
          { item: "空调清洗", price: "¥80.00" },
          { item: "冰箱维修", price: "¥100.00起" },
          { item: "洗衣机维修", price: "¥90.00起" }
        ],
        reviews: [
          { name: "赵女士", avatar: "https://picsum.photos/id/1062/100/100", rating: 5, content: "王师傅技术很好,很快就修好了我的洗衣机,收费也合理,推荐!" },
          { name: "孙先生", avatar: "https://picsum.photos/id/1074/100/100", rating: 5, content: "服务很专业,提前沟通了故障情况,上门后迅速解决,非常满意。" }
        ],
        availableTimes: {
          "今天": ["10:00-12:00", "15:00-17:00"],
          "明天": ["09:00-11:00", "13:00-15:00", "17:00-19:00"],
          "后天": ["08:00-10:00", "11:00-13:00", "14:00-16:00", "18:00-20:00"]
        }
      },
      {
        id: 3,
        name: "刘阿姨",
        avatar: "https://picsum.photos/id/1062/200/200",
        serviceType: "母婴护理",
        rating: 4.9,
        reviews: 156,
        experience: "10年经验",
        distance: "1.8公里",
        verified: "已认证",
        description: "专业母婴护理师,持有高级育婴师证书,擅长新生儿护理、产妇护理、月子餐制作等。有丰富的经验,耐心细致,让您和宝宝得到最贴心的照顾。",
        pricing: [
          { item: "日常母婴护理(8小时)", price: "¥350.00" },
          { item: "月子餐制作", price: "¥200.00/天" },
          { item: "新生儿洗澡抚触", price: "¥80.00" }
        ],
        reviews: [
          { name: "陈女士", avatar: "https://picsum.photos/id/1000/100/100", rating: 5, content: "刘阿姨非常专业,对宝宝很有耐心,照顾得无微不至,做的月子餐也很美味。" },
          { name: "林先生", avatar: "https://picsum.photos/id/1012/100/100", rating: 4, content: "服务很好,经验丰富,解答了我们很多育儿问题,非常感谢。" }
        ],
        availableTimes: {
          "今天": ["14:00-22:00"],
          "明天": ["08:00-16:00", "16:00-24:00"],
          "后天": ["08:00-16:00", "16:00-24:00"]
        }
      },
      {
        id: 4,
        name: "赵师傅",
        avatar: "https://picsum.photos/id/1074/200/200",
        serviceType: "管道疏通",
        rating: 4.7,
        reviews: 89,
        experience: "6年经验",
        distance: "4.2公里",
        verified: "已认证",
        description: "专业管道疏通服务,精通马桶疏通、下水道疏通、地漏疏通等。采用专业设备,高效解决各类堵塞问题,提供质保服务,不通不收费。",
        pricing: [
          { item: "马桶疏通", price: "¥80.00" },
          { item: "下水道疏通", price: "¥100.00" },
          { item: "地漏疏通", price: "¥60.00" }
        ],
        reviews: [
          { name: "郑女士", avatar: "https://picsum.photos/id/1027/100/100", rating: 5, content: "赵师傅技术很好,很快就疏通了我家堵塞的下水道,收费合理,值得推荐。" },
          { name: "吴先生", avatar: "https://picsum.photos/id/1066/100/100", rating: 4, content: "服务及时,态度很好,解决问题很专业,满意。" }
        ],
        availableTimes: {
          "今天": ["09:00-11:00", "13:00-15:00", "16:00-18:00", "19:00-21:00"],
          "明天": ["08:00-10:00", "11:00-13:00", "14:00-16:00"],
          "后天": ["10:00-12:00", "15:00-17:00", "18:00-20:00"]
        }
      }
    ];

    // 模拟数据 - 支付方式
    const paymentMethods = [
      { id: 1, name: "微信支付", icon: "fa-weixin", color: "text-green-500" },
      { id: 2, name: "支付宝", icon: "fa-credit-card", color: "text-blue-500" },
      { id: 3, name: "银行卡支付", icon: "fa-university", color: "text-gray-700" }
    ];

    // 全局状态
    const state = {
      currentCity: "",
      selectedWorker: null,
      selectedDate: "",
      selectedTimeSlot: "",
      selectedPaymentMethod: 1,
      selectedServiceItem: "",
      selectedServicePrice: ""
    };

    // DOM 元素
    const elements = {
      // 页面
      cityPage: document.getElementById('cityPage'),
      serviceListPage: document.getElementById('serviceListPage'),
      serviceDetailPage: document.getElementById('serviceDetailPage'),
      bookingTimePage: document.getElementById('bookingTimePage'),
      paymentPage: document.getElementById('paymentPage'),
      successPage: document.getElementById('successPage'),
      
      // 城市页面
      hotCities: document.getElementById('hotCities'),
      allCities: document.getElementById('allCities'),
      citySearch: document.getElementById('citySearch'),
      
      // 服务列表页面
      serviceWorkersList: document.getElementById('serviceWorkersList'),
      currentCityText: document.getElementById('currentCityText'),
      
      // 详情页面
      detailAvatar: document.getElementById('detailAvatar'),
      detailName: document.getElementById('detailName'),
      detailServiceType: document.getElementById('detailServiceType'),
      detailRating: document.getElementById('detailRating'),
      detailExperience: document.getElementById('detailExperience'),
      detailDistance: document.getElementById('detailDistance'),
      detailVerified: document.getElementById('detailVerified'),
      detailDescription: document.getElementById('detailDescription'),
      detailPricing: document.getElementById('detailPricing'),
      detailReviews: document.getElementById('detailReviews'),
      bookServiceBtn: document.getElementById('bookServiceBtn'),
      
      // 预约时间页面
      bookingAvatar: document.getElementById('bookingAvatar'),
      bookingName: document.getElementById('bookingName'),
      bookingServiceType: document.getElementById('bookingServiceType'),
      dateSelector: document.getElementById('dateSelector'),
      timeSlots: document.getElementById('timeSlots'),
      confirmTimeBtn: document.getElementById('confirmTimeBtn'),
      
      // 支付页面
      paymentAvatar: document.getElementById('paymentAvatar'),
      paymentName: document.getElementById('paymentName'),
      paymentServiceType: document.getElementById('paymentServiceType'),
      paymentCity: document.getElementById('paymentCity'),
      paymentDateTime: document.getElementById('paymentDateTime'),
      paymentServiceItem: document.getElementById('paymentServiceItem'),
      paymentAmount: document.getElementById('paymentAmount'),
      totalPayment: document.getElementById('totalPayment'),
      paymentMethods: document.getElementById('paymentMethods'),
      completePaymentBtn: document.getElementById('completePaymentBtn'),
      
      // 成功页面
      orderNumber: document.getElementById('orderNumber'),
      orderDateTime: document.getElementById('orderDateTime'),
      orderWorkerName: document.getElementById('orderWorkerName'),
      backToHomeBtn: document.getElementById('backToHomeBtn'),
      
      // 导航按钮
      backBtn: document.getElementById('backBtn')
    };

    // 初始化城市页面
    function initCityPage() {
      // 渲染热门城市
      elements.hotCities.innerHTML = cityData.hotCities.map(city => `
        <button class="city-btn bg-white border border-gray-200 hover:border-primary hover:text-primary rounded-lg py-3 text-center transition-custom" data-city="${city}">
          ${city}
        </button>
      `).join('');
      
      // 渲染所有城市
      elements.allCities.innerHTML = cityData.allCities.map(group => `
        <div>
          <h4 class="text-sm font-semibold text-light mb-2">${group.letter}</h4>
          <div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-2">
            ${group.cities.map(city => `
              <button class="city-btn text-left py-2 px-1 hover:text-primary transition-custom" data-city="${city}">
                ${city}
              </button>
            `).join('')}
          </div>
        </div>
      `).join('');
      
      // 添加城市选择事件
      document.querySelectorAll('.city-btn').forEach(btn => {
        btn.addEventListener('click', () => {
          state.currentCity = btn.getAttribute('data-city');
          goToServiceListPage();
        });
      });
      
      // 城市搜索功能
      elements.citySearch.addEventListener('input', (e) => {
        const searchTerm = e.target.value.toLowerCase();
        document.querySelectorAll('.city-btn').forEach(btn => {
          const city = btn.getAttribute('data-city').toLowerCase();
          if (city.includes(searchTerm)) {
            btn.style.display = '';
          } else {
            btn.style.display = 'none';
          }
        });
      });
    }

    // 初始化服务列表页面
    function initServiceListPage() {
      elements.currentCityText.textContent = `当前城市:${state.currentCity}`;
      
      // 渲染服务人员列表
      elements.serviceWorkersList.innerHTML = serviceWorkersData.map(worker => `
        <div class="service-worker-card bg-white rounded-xl overflow-hidden card-shadow hover:shadow-lg transition-custom cursor-pointer" data-id="${worker.id}">
          <div class="p-5 flex">
            <img src="${worker.avatar}" alt="${worker.name}" class="w-16 h-16 rounded-full object-cover mr-4">
            <div class="flex-1">
              <div class="flex justify-between">
                <h3 class="font-bold text-lg">${worker.name}</h3>
                <div class="flex items-center text-yellow-500">
                  <i class="fa fa-star text-xs"></i>
                  <span class="ml-1 text-sm">${worker.rating}</span>
                </div>
              </div>
              <p class="text-light text-sm mb-2">${worker.serviceType}</p>
              <div class="flex flex-wrap gap-2">
                <span class="bg-neutral px-2 py-1 rounded text-xs">${worker.experience}</span>
                <span class="bg-neutral px-2 py-1 rounded text-xs">${worker.distance}</span>
                <span class="bg-neutral px-2 py-1 rounded text-xs">${worker.verified}</span>
              </div>
              <div class="mt-3 flex justify-between items-center">
                <div>
                  <span class="text-secondary font-bold">${worker.pricing[0].price}</span>
                  <span class="text-light text-sm">起</span>
                </div>
                <span class="text-xs text-light">${worker.reviews}条评价</span>
              </div>
            </div>
          </div>
        </div>
      `).join('');
      
      // 添加服务人员点击事件
      document.querySelectorAll('.service-worker-card').forEach(card => {
        card.addEventListener('click', () => {
          const workerId = parseInt(card.getAttribute('data-id'));
          state.selectedWorker = serviceWorkersData.find(w => w.id === workerId);
          goToServiceDetailPage();
        });
      });
    }

    // 初始化服务详情页面
    function initServiceDetailPage() {
      const worker = state.selectedWorker;
      
      elements.detailAvatar.src = worker.avatar;
      elements.detailName.textContent = worker.name;
      elements.detailServiceType.textContent = worker.serviceType;
      elements.detailRating.textContent = worker.rating;
      elements.detailExperience.textContent = worker.experience;
      elements.detailDistance.textContent = worker.distance;
      elements.detailVerified.textContent = worker.verified;
      elements.detailDescription.textContent = worker.description;
      
      // 渲染价格列表
      elements.detailPricing.innerHTML = worker.pricing.map((item, index) => `
        <div class="flex justify-between items-center p-3 border-b ${index === worker.pricing.length - 1 ? 'border-0' : 'border-gray-100'} hover:bg-neutral rounded-lg cursor-pointer service-item" data-name="${item.item}" data-price="${item.price}">
          <span>${item.item}</span>
          <span class="text-secondary font-bold">${item.price}</span>
        </div>
      `).join('');
      
      // 默认选中第一个服务项目
      const firstServiceItem = document.querySelector('.service-item');
      if (firstServiceItem) {
        firstServiceItem.classList.add('bg-primary/5');
        state.selectedServiceItem = firstServiceItem.getAttribute('data-name');
        state.selectedServicePrice = firstServiceItem.getAttribute('data-price');
      }
      
      // 服务项目选择事件
      document.querySelectorAll('.service-item').forEach(item => {
        item.addEventListener('click', () => {
          document.querySelectorAll('.service-item').forEach(i => i.classList.remove('bg-primary/5'));
          item.classList.add('bg-primary/5');
          state.selectedServiceItem = item.getAttribute('data-name');
          state.selectedServicePrice = item.getAttribute('data-price');
        });
      });
      
      // 渲染评价
      elements.detailReviews.innerHTML = worker.reviews.map(review => `
        <div class="bg-white rounded-xl p-4 border border-gray-100">
          <div class="flex items-center mb-2">
            <img src="${review.avatar}" alt="${review.name}" class="w-8 h-8 rounded-full object-cover mr-2">
            <span class="font-medium text-sm">${review.name}</span>
            <div class="ml-auto flex text-yellow-500 text-xs">
              ${Array(review.rating).fill(0).map(() => '<i class="fa fa-star"></i>').join('')}
            </div>
          </div>
          <p class="text-sm">${review.content}</p>
        </div>
      `).join('');
      
      // 预约按钮事件
      elements.bookServiceBtn.addEventListener('click', goToBookingTimePage);
    }

    // 初始化预约时间页面
    function initBookingTimePage() {
      const worker = state.selectedWorker;
      
      elements.bookingAvatar.src = worker.avatar;
      elements.bookingName.textContent = worker.name;
      elements.bookingServiceType.textContent = worker.serviceType;
      
      // 生成日期选项
      const dates = Object.keys(worker.availableTimes);
      elements.dateSelector.innerHTML = dates.map((date, index) => `
        <button class="date-btn flex flex-col items-center justify-center p-3 bg-white border border-gray-200 rounded-lg transition-custom ${index === 0 ? 'border-primary bg-primary/5' : ''}" data-date="${date}">
          <span class="text-sm text-light">${date}</span>
          <span class="text-xs text-light mt-1">${getDateString(index)}</span>
        </button>
      `).join('');
      
      // 默认选中第一个日期
      state.selectedDate = dates[0];
      renderTimeSlots(worker.availableTimes[dates[0]]);
      
      // 日期选择事件
      document.querySelectorAll('.date-btn').forEach(btn => {
        btn.addEventListener('click', () => {
          document.querySelectorAll('.date-btn').forEach(b => b.classList.remove('border-primary', 'bg-primary/5'));
          btn.classList.add('border-primary', 'bg-primary/5');
          state.selectedDate = btn.getAttribute('data-date');
          renderTimeSlots(worker.availableTimes[state.selectedDate]);
        });
      });
      
      // 确认时间按钮事件
      elements.confirmTimeBtn.addEventListener('click', () => {
        if (!state.selectedTimeSlot) {
          alert('请选择服务时间段');
          return;
        }
        goToPaymentPage();
      });
    }

    // 渲染时间段
    function renderTimeSlots(times) {
      elements.timeSlots.innerHTML = times.map(time => `
        <button class="time-slot-btn py-3 px-2 bg-white border border-gray-200 rounded-lg text-center transition-custom hover:border-primary" data-time="${time}">
          ${time}
        </button>
      `).join('');
      
      // 时间段选择事件
      document.querySelectorAll('.time-slot-btn').forEach(btn => {
        btn.addEventListener('click', () => {
          document.querySelectorAll('.time-slot-btn').forEach(b => b.classList.remove('border-primary', 'bg-primary/5'));
          btn.classList.add('border-primary', 'bg-primary/5');
          state.selectedTimeSlot = btn.getAttribute('data-time');
        });
      });
    }

    // 获取日期字符串
    function getDateString(daysOffset) {
      const date = new Date();
      date.setDate(date.getDate() + daysOffset);
      const month = date.getMonth() + 1;
      const day = date.getDate();
      const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
      const weekday = weekdays[date.getDay()];
      return `${month}月${day}日 ${weekday}`;
    }

    // 初始化支付页面
    function initPaymentPage() {
      const worker = state.selectedWorker;
      
      elements.paymentAvatar.src = worker.avatar;
      elements.paymentName.textContent = worker.name;
      elements.paymentServiceType.textContent = worker.serviceType;
      elements.paymentCity.textContent = state.currentCity;
      elements.paymentDateTime.textContent = `${getDateString(Object.keys(worker.availableTimes).indexOf(state.selectedDate))} ${state.selectedTimeSlot}`;
      elements.paymentServiceItem.textContent = state.selectedServiceItem;
      elements.paymentAmount.textContent = state.selectedServicePrice;
      
      // 计算总金额
      const servicePrice = parseFloat(state.selectedServicePrice.replace('¥', ''));
      const total = servicePrice + 20 - 10; // 服务费20元,优惠券10元
      elements.totalPayment.textContent = `¥${total.toFixed(2)}`;
      
      // 渲染支付方式
      elements.paymentMethods.innerHTML = paymentMethods.map(method => `
        <div class="payment-method flex items-center p-3 border ${state.selectedPaymentMethod === method.id ? 'border-primary bg-primary/5' : 'border-gray-200'} rounded-lg cursor-pointer transition-custom" data-id="${method.id}">
          <i class="fa ${method.icon} ${method.color} text-xl mr-3"></i>
          <span>${method.name}</span>
          <i class="fa fa-check-circle ml-auto ${state.selectedPaymentMethod === method.id ? 'text-primary' : 'text-gray-300'}"></i>
        </div>
      `).join('');
      
      // 支付方式选择事件
      document.querySelectorAll('.payment-method').forEach(method => {
        method.addEventListener('click', () => {
          state.selectedPaymentMethod = parseInt(method.getAttribute('data-id'));
          initPaymentPage(); // 重新渲染以更新选中状态
        });
      });
      
      // 完成支付按钮事件
      elements.completePaymentBtn.addEventListener('click', goToSuccessPage);
    }

    // 初始化成功页面
    function initSuccessPage() {
      const worker = state.selectedWorker;
      
      // 生成随机订单号
      const orderNum = 'OD' + Date.now() + Math.floor(Math.random() * 1000);
      elements.orderNumber.textContent = orderNum;
      
      elements.orderDateTime.textContent = `${getDateString(Object.keys(worker.availableTimes).indexOf(state.selectedDate))} ${state.selectedTimeSlot}`;
      elements.orderWorkerName.textContent = worker.name;
      
      // 返回首页按钮事件
      elements.backToHomeBtn.addEventListener('click', () => {
        // 重置状态
        Object.keys(state).forEach(key => {
          state[key] = key === 'selectedPaymentMethod' ? 1 : '';
        });
        goToCityPage();
      });
    }

    // 页面导航
    function showPage(pageId) {
      // 隐藏所有页面
      document.querySelectorAll('.page').forEach(page => {
        page.classList.add('hidden');
      });
      
      // 显示目标页面
      const targetPage = document.getElementById(pageId);
      targetPage.classList.remove('hidden');
      
      // 添加动画效果
      targetPage.classList.add('page-enter');
      setTimeout(() => {
        targetPage.classList.add('page-enter-active');
      }, 10);
      setTimeout(() => {
        targetPage.classList.remove('page-enter', 'page-enter-active');
      }, 300);
      
      // 滚动到顶部
      window.scrollTo(0, 0);
    }

    // 导航到城市页面
    function goToCityPage() {
      showPage('cityPage');
      elements.backBtn.classList.add('hidden');
    }

    // 导航到服务列表页面
    function goToServiceListPage() {
      showPage('serviceListPage');
      elements.backBtn.classList.remove('hidden');
      initServiceListPage();
    }

    // 导航到服务详情页面
    function goToServiceDetailPage() {
      showPage('serviceDetailPage');
      elements.backBtn.classList.remove('hidden');
      initServiceDetailPage();
    }

    // 导航到预约时间页面
    function goToBookingTimePage() {
      showPage('bookingTimePage');
      elements.backBtn.classList.remove('hidden');
      initBookingTimePage();
    }

    // 导航到支付页面
    function goToPaymentPage() {
      showPage('paymentPage');
      elements.backBtn.classList.remove('hidden');
      initPaymentPage();
    }

    // 导航到成功页面
    function goToSuccessPage() {
      showPage('successPage');
      elements.backBtn.classList.add('hidden');
      initSuccessPage();
    }

    // 返回按钮事件
    elements.backBtn.addEventListener('click', () => {
      // 判断当前显示的页面,返回上一级
      if (!elements.serviceListPage.classList.contains('hidden')) {
        goToCityPage();
      } else if (!elements.serviceDetailPage.classList.contains('hidden')) {
        goToServiceListPage();
      } else if (!elements.bookingTimePage.classList.contains('hidden')) {
        goToServiceDetailPage();
      } else if (!elements.paymentPage.classList.contains('hidden')) {
        goToBookingTimePage();
      }
    });

    // 初始化应用
    function initApp() {
      initCityPage();
      goToCityPage();
    }

    // 启动应用
    document.addEventListener('DOMContentLoaded', initApp);
  </script>
</body>
</html>

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐