微搭低代码MBA 培训管理系统实战 36——小程序端课程预约功能实现

目录

前情回顾与本节目标

在上一节中,我们完成了教务端的预约管理功能。本节我们将实现小程序端的课程预约功能,学员可以查看可预约的课程列表,进行预约和取消预约操作。

本节核心目标:

  • 课程列表展示:显示可预约的课程列表,包含课程信息和名额状态
  • 预约功能:学员可以预约课程,扣减剩余名额
  • 取消预约:学员可以取消已预约的课程
  • 黑名单校验:黑名单学员无法预约

第一步:数据模型准备

1.1 预约课程表(MBA_BookingCourses)

字段名称 字段标识 字段类型 说明
课程ID _id 文本 主键,系统自动生成
关联课程 rel_schedule_id 多对一 关联 Schedules 表
课程名称 course_name 文本 课程名称
授课教师 teacher_name 文本 教师姓名
上课日期 course_date 日期 上课日期
开始时间 start_time 时间 开始时间
结束时间 end_time 时间 结束时间
总名额 total_spots 数字 总名额
剩余名额 remaining_spots 数字 剩余名额
预约状态 status 枚举 1-可预约、2-已约满、3-已结束

1.2 预约记录表(MBA_Bookings)

字段名称 字段标识 字段类型 说明
预约ID _id 文本 主键,系统自动生成
关联课程 rel_course_id 多对一 关联 BookingCourses 表
关联学员 rel_student_id 多对一 关联 StudentProfiles 表
预约状态 status 枚举 1-已预约、2-已签到、3-缺勤、4-已取消
预约时间 book_time 日期时间 预约时间

第二步:创建页面

点击创建页面 图标,输入"课程预约"

切换到布局设计,选择tab栏导航布局,加入菜单


第三步:页面布局

切回到页面设计,添加容器组件,设置宽、高和背景色:

css 复制代码
:root {
  width: 100%;
  min-height: 100vh;
  background-color: #F6F7F9;
}

继续添加普通容器,设置背景色、内边距和圆角:

css 复制代码
:root {
  background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
  padding: 48px 20px 24px 20px;
  border-radius: 0 0 24px 24px;
}

里边添加文本组件,设置文本颜色、字号和加粗的效果:


第四步:预约规则说明

4.1 规则展开区域

添加普通容器,里边添加两个普通容器,设置外层容器的布局为横向排列,两端对齐

内层的第一个普通容器里添加图标和文本组件,设置横向排列

内层的第二个普通容器里添加两个按钮组件

然后配置背景色、圆角、内外边距

4.2 规则展开收起

创建一个自定义变量用来控制按钮的显示

给按钮配置条件展示

bash 复制代码
$w.page.dataset.state.showRules

另外一个按钮进行取反

bash 复制代码
!$w.page.dataset.state.showRules

给按钮配置点击事件,对变量进行赋值

添加普通容器,里边添加文本组件,用来显示规则说明

绑定条件展示

bash 复制代码
!$w.page.dataset.state.showRules

第五步:课程列表区域

添加数据列表组件 ,数据模型选择预约课程表

设置数据列表的第一个普通容器的背景色、外阴影和圆角

清掉默认的布局组件,里边添加三个普通容器

第一个普通容器里添加两个文本组件,设置横向排列,两端对齐

分别绑定课程名称、预约状态字段

bash 复制代码
$w.item_listView1.course_name
bash 复制代码
$w.app.utils.formatEnum($w.item_listView1.status, 'yuyuezhuangtai', $w.app)

第二个普通容器添加三个普通容器,里边添加图标和文本组件,文本组件绑定上课日期时间

bash 复制代码
$w.DateText($w.item_listView1.created, 'MM月DD日')+$w.DateText($w.item_listView1.start_time, 'HH:mm')+"-"+$w.DateText($w.item_listView1.end_time, 'HH:mm')

按照同样的方法配置其余字段

bash 复制代码
$w.item_listView1.teacher_name
bash 复制代码
"剩余"+($w.item_listView1.remaining_spots||0)+"/"+$w.item_listView1.total_spots+"名额"

在第三个容器里添加按钮组件,修改文本为立即预约

第六步:预约功能实现

创建自定义方法 bookCourse

javascript 复制代码
export default async function bookCourse({ event, data }) {
  try {
    const course = data.target;
    const userInfo = $w.app.dataset.state.currentUser;
    
    // 校验是否登录
    if (!userInfo) {
      return $w.utils.showToast({ title: '请先登录', icon: 'error' });
    }
    
    // 校验黑名单
    if (userInfo.is_blacklisted) {
      return $w.utils.showModal({
        title: '提示',
        content: '您已被加入黑名单,无法预约课程,请联系老师解除',
        showCancel: false
      });
    }
    
    // 校验名额
    if (course.remaining_spots <= 0) {
      return $w.utils.showToast({ title: '名额已满', icon: 'error' });
    }
    
    // 校验是否已经预约(查询预约记录表)
    const existingBookingRes = await $w.cloud.callDataSource({
      dataSourceName: 'MBA_Bookings',
      methodName: 'wedaGetRecordsV2',
      params: {
        filter: {
          where: {
            $and: [
              { rel_course_id: { $eq: course._id } },
              { rel_student_id: { $eq: userInfo._id } },
              { status: { $eq: '1' } }  // 已预约状态
            ]
          }
        },
        select: { $master: true }
      }
    });
    
    if (existingBookingRes.records && existingBookingRes.records.length > 0) {
      return $w.utils.showToast({ title: '已预约该课程', icon: 'none' });
    }

    $w.utils.showLoading({ title: '预约中...' });
    
    // 创建预约记录
    await $w.cloud.callDataSource({
      dataSourceName: 'MBA_Bookings',
      methodName: 'wedaCreateV2',
      params: {
        data: {
          rel_course_id: { _id: course._id },
          rel_student_id: { _id: userInfo._id },
          status: '1',
          book_time: $w.Now()
        }
      }
    });
    
    // 更新课程剩余名额
    await $w.cloud.callDataSource({
      dataSourceName: 'MBA_BookingCourses',
      methodName: 'wedaUpdateV2',
      params: {
        data: {
          remaining_spots: course.remaining_spots - 1
        },
        filter: {
          where: {
            _id: { $eq: course._id }
          }
        }
      }
    });
    
    $w.utils.hideLoading();
    $w.utils.showToast({ title: '预约成功', icon: 'success' });
    
    // 刷新列表
    $w.listView1.refresh({})
    
  } catch (e) {
    console.error('预约失败', e);
    $w.utils.hideLoading();
    $w.utils.showToast({ title: '预约失败', icon: 'error' });
  }
}

给按钮设置点击事件,调用方法,传入所在行数据


最终效果

进入首页,点击课程预约,可以看到可供预约的课程

总结

本节完成了小程序端课程预约功能的实现:

  1. 课程列表展示:显示可预约课程,包含课程信息、名额状态
  2. 预约功能:学员预约课程,扣减剩余名额
  3. 取消预约:学员取消已预约课程,恢复名额
  4. 黑名单校验:黑名单学员无法预约
相关推荐
万岳科技系统开发1 小时前
小程序直播架构调整指南:H5嵌套模式的优化与替代方案
小程序·架构
Greg_Zhong3 小时前
学习AI 工程师第 3 天:小程序中调用豆包模型,实现ai助手(打字机效果与流式输出)
小程序·ai工程师·小程序调用豆包实现ai助手
于先生吖3 小时前
家政派单小程序定制厂家
大数据·小程序
00后程序员张4 小时前
完整指南 iOS App上架到App Store的步骤详解
macos·ios·小程序·uni-app·objective-c·cocoa·iphone
久爱@勿忘4 小时前
uniappH5跳转小程序
前端·小程序·uni-app
文慧的科技江湖1 天前
光储充一体化开源能源管理系统 需求说明书(简单版) - 慧知开源充电桩平台
小程序·开源·能源·光储充·光伏系统·实现光储充全设备统一监控·光储充一体化开源能源管理系统
eric*16881 天前
Mac反编译小程序教程
小程序·小程序反编译
C澒1 天前
AI 生码 - API2CODE:接口智能匹配与 API 自动化生码实践
前端·低代码·ai编程
打瞌睡的朱尤1 天前
微信小程序50~75
微信小程序·小程序