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.