目录
- 前情回顾与本节目标
- 第一步:数据模型准备
- 1.1 预约课程表(MBA_BookingCourses)
- 1.2 预约记录表(MBA_Bookings)
- 第二步:创建页面
- 第三步:页面布局
- 第四步:预约规则说明
- 4.1 规则展开区域
- 4.2 规则展开收起
- 第五步:课程列表区域
- 第六步:预约功能实现
- 最终效果
- 总结
前情回顾与本节目标
在上一节中,我们完成了教务端的预约管理功能。本节我们将实现小程序端的课程预约功能,学员可以查看可预约的课程列表,进行预约和取消预约操作。
本节核心目标:
- 课程列表展示:显示可预约的课程列表,包含课程信息和名额状态
- 预约功能:学员可以预约课程,扣减剩余名额
- 取消预约:学员可以取消已预约的课程
- 黑名单校验:黑名单学员无法预约
第一步:数据模型准备
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栏导航布局,加入菜单
第三步:页面布局
切回到页面设计,添加容器组件,设置宽、高和背景色:
:root{width:100%;min-height:100vh;background-color:#F6F7F9;}继续添加普通容器,设置背景色、内边距和圆角:
:root{background:linear-gradient(135deg,#3b82f6 0%,#1d4ed8 100%);padding:48px 20px 24px 20px;border-radius:0 0 24px 24px;}里边添加文本组件,设置文本颜色、字号和加粗的效果:
第四步:预约规则说明
4.1 规则展开区域
添加普通容器,里边添加两个普通容器,设置外层容器的布局为横向排列,两端对齐
内层的第一个普通容器里添加图标和文本组件,设置横向排列
内层的第二个普通容器里添加两个按钮组件
然后配置背景色、圆角、内外边距
4.2 规则展开收起
创建一个自定义变量用来控制按钮的显示
给按钮配置条件展示
$w.page.dataset.state.showRules另外一个按钮进行取反
!$w.page.dataset.state.showRules给按钮配置点击事件,对变量进行赋值
添加普通容器,里边添加文本组件,用来显示规则说明
绑定条件展示
!$w.page.dataset.state.showRules第五步:课程列表区域
添加数据列表组件,数据模型选择预约课程表
设置数据列表的第一个普通容器的背景色、外阴影和圆角
清掉默认的布局组件,里边添加三个普通容器
第一个普通容器里添加两个文本组件,设置横向排列,两端对齐
分别绑定课程名称、预约状态字段
$w.item_listView1.course_name$w.app.utils.formatEnum($w.item_listView1.status,'yuyuezhuangtai',$w.app)第二个普通容器添加三个普通容器,里边添加图标和文本组件,文本组件绑定上课日期时间
$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')按照同样的方法配置其余字段
$w.item_listView1.teacher_name"剩余"+($w.item_listView1.remaining_spots||0)+"/"+$w.item_listView1.total_spots+"名额"在第三个容器里添加按钮组件,修改文本为立即预约
第六步:预约功能实现
创建自定义方法bookCourse:
exportdefaultasyncfunctionbookCourse({event,data}){try{constcourse=data.target;constuserInfo=$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'});}// 校验是否已经预约(查询预约记录表)constexistingBookingRes=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'});}}给按钮设置点击事件,调用方法,传入所在行数据
最终效果
进入首页,点击课程预约,可以看到可供预约的课程
总结
本节完成了小程序端课程预约功能的实现:
- 课程列表展示:显示可预约课程,包含课程信息、名额状态
- 预约功能:学员预约课程,扣减剩余名额
- 取消预约:学员取消已预约课程,恢复名额
- 黑名单校验:黑名单学员无法预约