家政服务小程序设计与实现,耗时近两个月成功交付

503 阅读6分钟

家政服务小程序设计与实现

一、系统设计

(一)系统架构设计

本家政服务系统基于微信小程序云开发,采用前后端分离的架构。前端是微信小程序,负责与用户进行交互,展示各种功能界面,如首页、服务详情页、预约表单页、订单列表页等。后端依托微信云开发提供的云函数、云数据库和云存储等服务。云函数用于处理业务逻辑,如订单生成、服务人员调度等;云数据库用于存储用户信息、服务信息、订单信息等数据;云存储用于存储服务人员头像、用户上传的图片等文件。

(二)功能模块设计

  1. 用户管理模块:包括用户注册登录、个人信息管理。用户可以通过微信授权快速注册登录,登录后可修改昵称、联系方式、地址等个人信息。

  2. 服务展示模块:展示各类家政服务,如保洁、家电清洗、月嫂等。每个服务有详细介绍,包括服务内容、价格、服务时长、服务人员技能要求等。同时,展示热门服务推荐,方便用户选择。

  3. 预约下单模块:用户选择服务项目、服务时间、服务人员(可选),填写预约地址等信息后提交订单。系统会验证服务时间是否冲突、地址是否合法等。

  4. **[订单管理模块

    ](zhida.zhihu.com/search?cont…

  5. 服务人员管理模块:管理员可对服务人员进行管理,添加、删除、修改服务人员信息,设置其技能、服务区域、工作时间等。

  6. 评价管理模块:用户对完成的服务进行评价,评价内容包括服务质量、态度、效率等。评价信息对其他用户和服务人员公开,作为选择和改进服务的参考。

(三)数据库设计

  1. 用户表(users):存储用户信息,包括用户ID、昵称、微信openid、联系方式、地址等。
  2. 服务人员表(service_providers):存储服务人员信息,如服务人员ID、姓名、性别、联系方式、技能、服务区域、工作时间、头像等。
  3. 服务项目表(services):存储家政服务项目信息,包括服务项目ID、服务名称、服务内容、价格、服务时长等。
  4. 订单表(orders):存储订单信息,如订单ID、用户ID、服务项目ID、服务人员ID(可为空,下单时未指定)、服务时间、预约地址、订单状态、支付状态等。
  5. 评价表(reviews):存储用户对服务的评价信息,包括评价ID、订单ID、用户ID、服务人员ID、评分、评价内容等。

(四)接口设计

  1. 用户接口:提供微信授权登录、获取用户信息、更新用户信息等接口。
  2. 服务接口:获取服务项目列表、服务项目详情等接口。
  3. 预约接口:提交预约订单、获取预约表单信息等接口。
  4. 订单接口:获取订单列表、支付订单、取消订单、评价订单等接口。
  5. 服务人员接口:获取服务人员列表、服务人员详情等接口。

二、系统实现

(一)开发环境与技术选型

  1. 开发环境:微信开发者工具用于小程序前端开发和调试,云开发控制台用于后端云函数、数据库和存储的管理。
  2. 技术选型
  • 前端:微信小程序框架,使用WXML、WXSS和JavaScript进行页面结构和样式、逻辑的编写。

  • 后端:微信云开发,利用云函数处理业务逻辑,云数据库进行数据存储和查询,云存储存储文件。

(二)关键功能实现

1、微信授权登录

  • 前端:在小程序页面中调用wx.login()获取临时登录凭证(code),然后调用wx.getUserInfo()获取用户信息,将code和用户信息发送到后端云函数。

  • 后端:云函数接收code和用户信息,通过微信提供的接口用code换取openid和session_key,将用户信息存储到用户表中,返回用户ID和登录态给前端。

2、预约下单

  • 前端:用户在预约表单页选择服务项目、服务时间、服务人员(可选)等信息,点击提交按钮后,将预约信息发送到后端云函数。

  • 后端:云函数验证服务时间是否冲突、预约地址是否合法等,若验证通过,生成订单并存储到订单表中,同时通知相应的服务人员(可通过消息推送等方式)。

3、订单支付

  • 前端:在订单详情页点击支付按钮,调用微信支付接口,将支付信息发送到微信支付服务器。

  • 后端:接收微信支付服务器返回的支付结果通知,更新订单的支付状态。

4、服务人员调度

  • 后端:云函数根据用户的预约信息和服务人员的排班情况,采用一定的算法(如贪心算法)进行服务人员调度,将调度结果通知服务人员。

(三)关键代码实现

1、首页(展示家政服务分类、热门推荐等)

pages/home/home.wxml

<view class="container">
  <!-- 服务分类 -->
  <view class="service-category">
    <text class="title">服务分类</text>
    <view class="category-list">
      <block wx:for="{{serviceCategories}}" wx:key="index">
        <view class="category-item">{{item}}</view>
      </block>
    </view>
  </view>
  <!-- 热门推荐 -->
  <view class="hot-recommend">
    <text class="title">热门推荐</text>
    <view class="recommend-list">
      <block wx:for="{{hotRecommendations}}" wx:key="index">
        <view class="recommend-item">{{item}}</view>
      </block>
    </view>
  </view>
</view>

pages/home/home.js

Page({
  data: {
    serviceCategories: [],
    hotRecommendations: []
  },
  onLoad: function () {
    this.loadServiceCategories();
    this.loadHotRecommendations();
  },
  loadServiceCategories: function () {
    // 这里调用云函数获取服务分类数据
    this.setData({
      serviceCategories: ["保洁", "家电维修", "月嫂"]
    });
  },
  loadHotRecommendations: function () {
    // 热门推荐数据
    this.setData({
      hotRecommendations: ["深度保洁", "空调清洗", "月嫂服务"]
    });
  }
});

后端云函数 - getServiceCategories

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();

// 云函数入口函数
exports.main = async (event, context) => {
  return {
    serviceCategories: ["保洁", "家电维修", "月嫂"]
  };
};

后端云函数 - getHotRecommendations

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();

// 云函数入口函数
exports.main = async (event, context) => {
  return {
    hotRecommendations: ["深度保洁", "空调清洗", "月嫂服务"]
  };
}; 

2、家政服务详情页(展示服务价格、服务内容等)

pages/serviceDetail/serviceDetail.wxml

<view class="container">
  <view class="service-info">
    <text class="service-name">{{serviceDetail.name}}</text>
    <text class="service-price">价格:¥{{serviceDetail.price}}</text>
    <text class="service-content">{{serviceDetail.content}}</text>
  </view>
  <button bindtap="makeAppointment">立即预约</button>
</view> 

pages/serviceDetail/serviceDetail.js

Page({
  data: {
    serviceDetail: {}
  },
  onLoad: function (options) {
    const serviceId = options.serviceId;
    this.loadServiceDetail(serviceId);
  },
  loadServiceDetail: function (serviceId) {
    // 这里调用云函数获取服务详情数据
    let detail;
    switch (serviceId) {
      case "1":
        detail = {
          name: "深度保洁",
          price: 199,
          content: "包含客厅、卧室、厨房、卫生间全面清洁"
        };
        break;
      // 其他服务详情...
    }
    this.setData({
      serviceDetail: detail
    });
  },
  makeAppointment: function () {
    wx.navigateTo({
      url: `/pages/appointmentForm/appointmentForm?serviceId=${this.data.serviceDetail.id}`
    });
  }
}); 

后端云函数 - getServiceDetail

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();

// 云函数入口函数
exports.main = async (event, context) => {
  const serviceId = event.serviceId;
  let detail;
  switch (serviceId) {
    case "1":
      detail = {
        name: "深度保洁",
        price: 199,
        content: "包含客厅、卧室、厨房、卫生间全面清洁"
      };
      break;
    // 其他服务详情...
  }
  return {
    serviceDetail: detail
  };
}; 

3、预约表单页(填写服务地址、选择服务时间等)

pages/appointmentForm/appointmentForm.wxml

<view class="container">
  <view class="form-item">
    <text>服务地址</text>
    <input placeholder="请输入服务地址" bindinput="inputAddress" />
  </view>
  <view class="form-item">
    <text>服务时间</text>
    <picker mode="date" bindchange="selectDate">
      <view>{{selectedDate || '请选择日期'}}</view>
    </picker>
    <picker mode="time" bindchange="selectTime">
      <view>{{selectedTime || '请选择时间'}}</view>
    </picker>
  </view>
  <button bindtap="submitAppointment">提交预约</button>
</view>

pages/appointmentForm/appointmentForm.js

Page({
  data: {
    serviceId: "",
    address: "",
    selectedDate: "",
    selectedTime: ""
  },
  onLoad: function (options) {
    this.setData({
      serviceId: options.serviceId
    });
  },
  inputAddress: function (e) {
    this.setData({
      address: e.detail.value
    });
  },
  selectDate: function (e) {
    this.setData({
      selectedDate: e.detail.value
    });
  },
  selectTime: function (e) {
    this.setData({
      selectedTime: e.detail.value
    });
  },
  submitAppointment: function () {
    const { serviceId, address, selectedDate, selectedTime } = this.data;
    if (!address ||!selectedDate ||!selectedTime) {
      wx.showToast({
        title: '请填写完整信息',
        icon: 'none'
      });
      return;
    }
    wx.cloud.callFunction({
      name: 'submitAppointment',
      data: {
        serviceId,
        address,
        selectedDate,
        selectedTime
      },
      success: res => {
        wx.showToast({
          title: '预约成功',
          icon: 'success'
        });
        wx.navigateBack();
      },
      fail: err => {
        wx.showToast({
          title: '预约失败,请重试',
          icon: 'none'
        });
      }
    });
  }
});

后端云函数 - submitAppointment

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();

// 云函数入口函数
exports.main = async (event, context) => {
  const { serviceId, address, selectedDate, selectedTime } = event;
  // 这里可以进行服务时间冲突验证、地址合法性验证等
  // 生成订单并存储到数据库
  try {
    await db.collection('orders').add({
      data: {
        serviceId,
        address,
        appointmentTime: `${selectedDate} ${selectedTime}`,
        status: '待支付'
      }
    });
    return {
      success: true
    };
  } catch (error) {
    return {
      success: false,
      error
    };
  }
};

4、订单列表页(展示用户订单状态等)

pages/orderList/orderList.wxml

<view class="container">
  <view class="order-item" wx:for="{{orderList}}" wx:key="index">
    <view class="order-info">
      <text class="service-name">{{item.serviceName}}</text>
      <text class="order-status">{{item.status}}</text>
    </view>
    <view class="order-actions">
      <button wx:if="{{item.status === '待支付'}}" bindtap="payOrder" data-order-id="{{item._id}}">支付</button>
      <button wx:if="{{item.status === '待评价'}}" bindtap="evaluateOrder" data-order-id="{{item._id}}">评价</button>
    </view>
  </view>
</view> 

pages/orderList/orderList.js

Page({
  data: {
    orderList: []
  },
  onLoad: function () {
    this.loadOrderList();
  },
  loadOrderList: function () {
    wx.cloud.callFunction({
      name: 'getOrderList',
      success: res => {
        this.setData({
          orderList: res.result.orderList
        });
      },
      fail: err => {
        wx.showToast({
          title: '加载订单失败',
          icon: 'none'
        });
      }
    });
  },
  payOrder: function (e) {
    const orderId = e.currentTarget.dataset.orderId;
    // 调用微信支付接口等逻辑
  },
  evaluateOrder: function (e) {
    const orderId = e.currentTarget.dataset.orderId;
    wx.navigateTo({
      url: `/pages/evaluateOrder/evaluateOrder?orderId=${orderId}`
    });
  }
}); 

后端云函数 - getOrderList

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    const orderList = await db.collection('orders').get();
    return {
      orderList: orderList.data
    };
  } catch (error) {
    return {
      error
    };
  }
};

5、评价页(用户对服务进行评价)

pages/evaluateOrder/evaluateOrder.wxml

<view class="container">
  <view class="rating">
    <text>评分</text>
    <slider min="1" max="5" show-value bindchange="changeRating" />
  </view>
  <view class="comment">
    <text>评价内容</text>
    <textarea placeholder="请输入您的评价" bindinput="inputComment"></textarea>
  </view>
  <button bindtap="submitEvaluate">提交评价</button>
</view> 

pages/evaluateOrder/evaluateOrder.js

Page({
  data: {
    orderId: "",
    rating: 3,
    comment: ""
  },
  onLoad: function (options) {
    this.setData({
      orderId: options.orderId
    });
  },
  changeRating: function (e) {
    this.setData({
      rating: e.detail.value
    });
  },
  inputComment: function (e) {
    this.setData({
      comment: e.detail.value
    });
  },
  submitEvaluate: function () {
    const { orderId, rating, comment } = this.data;
    wx.cloud.callFunction({
      name: 'submitEvaluate',
      data: {
        orderId,
        rating,
        comment
      },
      success: res => {
        wx.showToast({
          title: '评价成功',
          icon: 'success'
        });
        wx.navigateBack();
      },
      fail: err => {
        wx.showToast({
          title: '评价失败,请重试',
          icon: 'none'
        });
      }
    });
  }
});

后端云函数 - submitEvaluate

// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();

// 云函数入口函数
exports.main = async (event, context) => {
  const { orderId, rating, comment } = event;
  try {
    await db.collection('reviews').add({
      data: {
        orderId,
        rating,
        comment
      }
    });
    await db.collection('orders').doc(orderId).update({
      data: {
        status: '已完成'
      }
    });
    return {
      success: true
    };
  } catch (error) {
    return {
      success: false,
      error
    };
  }
};