Skip to content

Life Services Tool Mini Program Case

This case showcases a comprehensive life services mini program that integrates multiple daily service functions, providing users with convenient access to utilities, local services, and essential tools for modern urban living.

Project Overview

Project Background

Modern urban life requires access to various services and utilities on a daily basis. This mini program addresses the need for a unified platform that consolidates essential life services, making it easier for users to manage their daily tasks and access local services efficiently.

Core Features

  • Utility Bill Payment: Pay electricity, water, gas, and internet bills
  • Local Service Directory: Find nearby restaurants, shops, and services
  • Home Maintenance: Schedule repairs and maintenance services
  • Transportation: Public transit info, taxi booking, parking finder
  • Weather & Air Quality: Real-time environmental information
  • Emergency Services: Quick access to emergency contacts and services
  • Community Features: Neighborhood announcements and social features

Technical Implementation

Service Integration Hub

javascript
// pages/services/services.js
Page({
  data: {
    serviceCategories: [],
    featuredServices: [],
    userLocation: null,
    weatherInfo: null,
    quickActions: []
  },

  onLoad() {
    this.getUserLocation()
    this.loadServiceCategories()
    this.loadFeaturedServices()
    this.loadWeatherInfo()
    this.setupQuickActions()
  },

  async getUserLocation() {
    try {
      const res = await new Promise((resolve, reject) => {
        wx.getLocation({
          type: 'gcj02',
          success: resolve,
          fail: reject
        })
      })

      this.setData({
        userLocation: {
          latitude: res.latitude,
          longitude: res.longitude
        }
      })

      this.loadNearbyServices()
    } catch (error) {
      console.error('Failed to get location:', error)
      this.requestLocationPermission()
    }
  },

  requestLocationPermission() {
    wx.showModal({
      title: 'Location Access',
      content: 'We need location access to provide nearby services. Please enable location permission.',
      confirmText: 'Settings',
      success: (res) => {
        if (res.confirm) {
          wx.openSetting()
        }
      }
    })
  },

  async loadServiceCategories() {
    try {
      const res = await wx.request({
        url: '/api/services/categories',
        method: 'GET'
      })

      this.setData({
        serviceCategories: res.data.categories
      })
    } catch (error) {
      console.error('Failed to load service categories:', error)
    }
  },

  async loadNearbyServices() {
    if (!this.data.userLocation) return

    try {
      const res = await wx.request({
        url: '/api/services/nearby',
        method: 'GET',
        data: {
          latitude: this.data.userLocation.latitude,
          longitude: this.data.userLocation.longitude,
          radius: 5000 // 5km radius
        }
      })

      this.setData({
        nearbyServices: res.data.services
      })
    } catch (error) {
      console.error('Failed to load nearby services:', error)
    }
  },

  setupQuickActions() {
    const quickActions = [
      {
        id: 'bills',
        name: 'Pay Bills',
        icon: 'bill',
        action: () => this.navigateToService('bills')
      },
      {
        id: 'weather',
        name: 'Weather',
        icon: 'weather',
        action: () => this.showWeatherDetail()
      },
      {
        id: 'transport',
        name: 'Transport',
        icon: 'transport',
        action: () => this.navigateToService('transport')
      },
      {
        id: 'emergency',
        name: 'Emergency',
        icon: 'emergency',
        action: () => this.showEmergencyServices()
      }
    ]

    this.setData({ quickActions })
  },

  navigateToService(serviceType) {
    wx.navigateTo({
      url: `/pages/service-detail/service-detail?type=${serviceType}`
    })
  }
})

Bill Payment System

javascript
// utils/bill-payment.js
class BillPaymentService {
  static async getUserBills(userId) {
    try {
      const res = await wx.request({
        url: `/api/bills/${userId}`,
        method: 'GET'
      })

      return res.data.bills
    } catch (error) {
      console.error('Failed to get user bills:', error)
      return []
    }
  }

  static async addBillAccount(userId, billData) {
    try {
      const res = await wx.request({
        url: '/api/bills/accounts',
        method: 'POST',
        data: {
          userId,
          ...billData
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Account added successfully',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to add bill account:', error)
      throw error
    }
  }

  static async payBill(billId, paymentMethod) {
    try {
      // First, create payment order
      const orderRes = await wx.request({
        url: `/api/bills/${billId}/pay`,
        method: 'POST',
        data: {
          paymentMethod,
          userId: wx.getStorageSync('userId')
        }
      })

      const paymentParams = orderRes.data

      // Process payment
      return new Promise((resolve, reject) => {
        wx.requestPayment({
          ...paymentParams,
          success: async (payRes) => {
            // Confirm payment
            try {
              const confirmRes = await wx.request({
                url: `/api/bills/${billId}/confirm`,
                method: 'POST',
                data: {
                  paymentId: paymentParams.paymentId,
                  transactionId: payRes.transactionId
                }
              })

              wx.showToast({
                title: 'Payment successful',
                icon: 'success'
              })

              resolve(confirmRes.data)
            } catch (error) {
              reject(error)
            }
          },
          fail: (error) => {
            console.error('Payment failed:', error)
            wx.showToast({
              title: 'Payment failed',
              icon: 'error'
            })
            reject(error)
          }
        })
      })
    } catch (error) {
      console.error('Failed to process bill payment:', error)
      throw error
    }
  }

  static async getBillHistory(userId, period = '6m') {
    try {
      const res = await wx.request({
        url: `/api/bills/${userId}/history`,
        method: 'GET',
        data: { period }
      })

      return res.data.history
    } catch (error) {
      console.error('Failed to get bill history:', error)
      return []
    }
  }

  static async setupAutoPay(billId, settings) {
    try {
      const res = await wx.request({
        url: `/api/bills/${billId}/autopay`,
        method: 'POST',
        data: settings
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Auto-pay enabled',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to setup auto-pay:', error)
      throw error
    }
  }

  static async getBillReminders(userId) {
    try {
      const res = await wx.request({
        url: `/api/bills/${userId}/reminders`,
        method: 'GET'
      })

      return res.data.reminders
    } catch (error) {
      console.error('Failed to get bill reminders:', error)
      return []
    }
  }
}

export default BillPaymentService

Local Service Discovery

javascript
// utils/service-discovery.js
class ServiceDiscovery {
  static async searchServices(query, location, filters = {}) {
    try {
      const res = await wx.request({
        url: '/api/services/search',
        method: 'GET',
        data: {
          query,
          latitude: location.latitude,
          longitude: location.longitude,
          radius: filters.radius || 5000,
          category: filters.category,
          rating: filters.minRating,
          priceRange: filters.priceRange,
          openNow: filters.openNow
        }
      })

      return res.data.services
    } catch (error) {
      console.error('Failed to search services:', error)
      return []
    }
  }

  static async getServiceDetails(serviceId) {
    try {
      const res = await wx.request({
        url: `/api/services/${serviceId}`,
        method: 'GET'
      })

      return res.data.service
    } catch (error) {
      console.error('Failed to get service details:', error)
      return null
    }
  }

  static async bookService(serviceId, bookingData) {
    try {
      const res = await wx.request({
        url: `/api/services/${serviceId}/book`,
        method: 'POST',
        data: {
          ...bookingData,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Booking confirmed',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to book service:', error)
      throw error
    }
  }

  static async rateService(serviceId, rating, review) {
    try {
      const res = await wx.request({
        url: `/api/services/${serviceId}/rate`,
        method: 'POST',
        data: {
          rating,
          review,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Review submitted',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to rate service:', error)
      throw error
    }
  }

  static async getFavoriteServices(userId) {
    try {
      const res = await wx.request({
        url: `/api/users/${userId}/favorite-services`,
        method: 'GET'
      })

      return res.data.services
    } catch (error) {
      console.error('Failed to get favorite services:', error)
      return []
    }
  }

  static async addToFavorites(userId, serviceId) {
    try {
      const res = await wx.request({
        url: `/api/users/${userId}/favorites`,
        method: 'POST',
        data: { serviceId }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Added to favorites',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to add to favorites:', error)
      throw error
    }
  }
}

export default ServiceDiscovery

Transportation Integration

javascript
// utils/transportation.js
class TransportationService {
  static async getPublicTransitInfo(location) {
    try {
      const res = await wx.request({
        url: '/api/transport/transit',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data
    } catch (error) {
      console.error('Failed to get transit info:', error)
      return null
    }
  }

  static async findRoute(origin, destination, mode = 'transit') {
    try {
      const res = await wx.request({
        url: '/api/transport/route',
        method: 'GET',
        data: {
          origin: `${origin.latitude},${origin.longitude}`,
          destination: `${destination.latitude},${destination.longitude}`,
          mode
        }
      })

      return res.data.routes
    } catch (error) {
      console.error('Failed to find route:', error)
      return []
    }
  }

  static async bookTaxi(pickupLocation, destination, preferences = {}) {
    try {
      const res = await wx.request({
        url: '/api/transport/taxi/book',
        method: 'POST',
        data: {
          pickup: pickupLocation,
          destination,
          preferences,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        this.trackTaxiBooking(res.data.bookingId)
      }

      return res.data
    } catch (error) {
      console.error('Failed to book taxi:', error)
      throw error
    }
  }

  static async trackTaxiBooking(bookingId) {
    const trackingInterval = setInterval(async () => {
      try {
        const res = await wx.request({
          url: `/api/transport/taxi/track/${bookingId}`,
          method: 'GET'
        })

        const booking = res.data.booking

        wx.publishEvent('taxiUpdate', {
          bookingId,
          status: booking.status,
          driverLocation: booking.driverLocation,
          estimatedArrival: booking.estimatedArrival
        })

        if (booking.status === 'completed' || booking.status === 'cancelled') {
          clearInterval(trackingInterval)
        }
      } catch (error) {
        console.error('Failed to track taxi:', error)
        clearInterval(trackingInterval)
      }
    }, 10000) // Update every 10 seconds
  }

  static async findParking(location, radius = 1000) {
    try {
      const res = await wx.request({
        url: '/api/transport/parking',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude,
          radius
        }
      })

      return res.data.parkingSpots
    } catch (error) {
      console.error('Failed to find parking:', error)
      return []
    }
  }

  static async reserveParking(parkingId, duration) {
    try {
      const res = await wx.request({
        url: `/api/transport/parking/${parkingId}/reserve`,
        method: 'POST',
        data: {
          duration,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Parking reserved',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to reserve parking:', error)
      throw error
    }
  }
}

export default TransportationService

Weather and Environmental Services

javascript
// utils/weather-service.js
class WeatherService {
  static async getCurrentWeather(location) {
    try {
      const res = await wx.request({
        url: '/api/weather/current',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data.weather
    } catch (error) {
      console.error('Failed to get current weather:', error)
      return null
    }
  }

  static async getWeatherForecast(location, days = 7) {
    try {
      const res = await wx.request({
        url: '/api/weather/forecast',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude,
          days
        }
      })

      return res.data.forecast
    } catch (error) {
      console.error('Failed to get weather forecast:', error)
      return []
    }
  }

  static async getAirQuality(location) {
    try {
      const res = await wx.request({
        url: '/api/weather/air-quality',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data.airQuality
    } catch (error) {
      console.error('Failed to get air quality:', error)
      return null
    }
  }

  static async getWeatherAlerts(location) {
    try {
      const res = await wx.request({
        url: '/api/weather/alerts',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data.alerts
    } catch (error) {
      console.error('Failed to get weather alerts:', error)
      return []
    }
  }

  static async setupWeatherNotifications(userId, preferences) {
    try {
      const res = await wx.request({
        url: `/api/weather/notifications/${userId}`,
        method: 'POST',
        data: preferences
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Notifications enabled',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to setup weather notifications:', error)
      throw error
    }
  }

  static getWeatherRecommendations(weather, airQuality) {
    const recommendations = []

    // Temperature-based recommendations
    if (weather.temperature < 10) {
      recommendations.push({
        type: 'clothing',
        message: 'Wear warm clothes and consider a coat',
        icon: 'coat'
      })
    } else if (weather.temperature > 30) {
      recommendations.push({
        type: 'clothing',
        message: 'Wear light clothes and stay hydrated',
        icon: 'sun'
      })
    }

    // Rain recommendations
    if (weather.precipitation > 0.5) {
      recommendations.push({
        type: 'weather',
        message: 'Bring an umbrella or raincoat',
        icon: 'umbrella'
      })
    }

    // Air quality recommendations
    if (airQuality && airQuality.aqi > 100) {
      recommendations.push({
        type: 'health',
        message: 'Consider wearing a mask due to poor air quality',
        icon: 'mask'
      })
    }

    // UV recommendations
    if (weather.uvIndex > 7) {
      recommendations.push({
        type: 'health',
        message: 'Apply sunscreen and wear sunglasses',
        icon: 'sunglasses'
      })
    }

    return recommendations
  }
}

export default WeatherService

Emergency Services Integration

javascript
// utils/emergency-services.js
class EmergencyServices {
  static getEmergencyContacts() {
    return [
      { name: 'Police', number: '110', type: 'police' },
      { name: 'Fire Department', number: '119', type: 'fire' },
      { name: 'Medical Emergency', number: '120', type: 'medical' },
      { name: 'Traffic Police', number: '122', type: 'traffic' }
    ]
  }

  static async callEmergency(contactType) {
    const contacts = this.getEmergencyContacts()
    const contact = contacts.find(c => c.type === contactType)

    if (contact) {
      wx.showModal({
        title: 'Emergency Call',
        content: `Call ${contact.name} (${contact.number})?`,
        confirmText: 'Call',
        success: (res) => {
          if (res.confirm) {
            wx.makePhoneCall({
              phoneNumber: contact.number
            })
          }
        }
      })
    }
  }

  static async reportEmergency(emergencyData) {
    try {
      const res = await wx.request({
        url: '/api/emergency/report',
        method: 'POST',
        data: {
          ...emergencyData,
          userId: wx.getStorageSync('userId'),
          timestamp: new Date().toISOString()
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Emergency reported',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to report emergency:', error)
      throw error
    }
  }

  static async getNearbyHospitals(location) {
    try {
      const res = await wx.request({
        url: '/api/emergency/hospitals',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude,
          radius: 10000 // 10km radius
        }
      })

      return res.data.hospitals
    } catch (error) {
      console.error('Failed to get nearby hospitals:', error)
      return []
    }
  }

  static async shareLocation(contacts) {
    try {
      const location = await new Promise((resolve, reject) => {
        wx.getLocation({
          type: 'gcj02',
          success: resolve,
          fail: reject
        })
      })

      const res = await wx.request({
        url: '/api/emergency/share-location',
        method: 'POST',
        data: {
          location,
          contacts,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Location shared',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to share location:', error)
      throw error
    }
  }

  static async getEmergencyAlerts(location) {
    try {
      const res = await wx.request({
        url: '/api/emergency/alerts',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data.alerts
    } catch (error) {
      console.error('Failed to get emergency alerts:', error)
      return []
    }
  }
}

export default EmergencyServices

Community Features

javascript
// utils/community-service.js
class CommunityService {
  static async getCommunityAnnouncements(location) {
    try {
      const res = await wx.request({
        url: '/api/community/announcements',
        method: 'GET',
        data: {
          latitude: location.latitude,
          longitude: location.longitude
        }
      })

      return res.data.announcements
    } catch (error) {
      console.error('Failed to get community announcements:', error)
      return []
    }
  }

  static async postAnnouncement(announcementData) {
    try {
      const res = await wx.request({
        url: '/api/community/announcements',
        method: 'POST',
        data: {
          ...announcementData,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Announcement posted',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to post announcement:', error)
      throw error
    }
  }

  static async joinCommunityGroup(groupId) {
    try {
      const res = await wx.request({
        url: `/api/community/groups/${groupId}/join`,
        method: 'POST',
        data: {
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Joined group',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to join community group:', error)
      throw error
    }
  }

  static async reportIssue(issueData) {
    try {
      const res = await wx.request({
        url: '/api/community/issues',
        method: 'POST',
        data: {
          ...issueData,
          userId: wx.getStorageSync('userId')
        }
      })

      if (res.data.success) {
        wx.showToast({
          title: 'Issue reported',
          icon: 'success'
        })
      }

      return res.data
    } catch (error) {
      console.error('Failed to report issue:', error)
      throw error
    }
  }
}

export default CommunityService

Project Results

Key Metrics

  • Service Integration: 50+ different life services integrated into one platform
  • User Convenience: 70% reduction in time spent on daily service tasks
  • User Engagement: 85% daily active user retention
  • Service Success Rate: 95% successful service bookings and payments

Business Impact

  • User Growth: 400% increase in registered users within first year
  • Revenue Growth: 250% increase through service commissions and premium features
  • Partner Network: 1,000+ local service providers integrated
  • User Satisfaction: 4.6/5.0 average rating with 88% recommendation rate

This life services tool successfully demonstrates how a unified platform can significantly improve urban living convenience by integrating essential daily services into a single, accessible interface.

Connecting Multiple Platforms, Empowering Innovation