微搭低代码MBA 培训管理系统实战 22——课程排课

微搭低代码MBA 培训管理系统实战 22——课程排课

目录

在上一讲中,我们完成了班级管理与花名册的搭建。学员已经分好班了,接下来教务老师面临的最头疼的工作就是排课。本讲将详细介绍如何实现排课功能,包括教室管理、课表设计以及核心的资源冲突检测机制。


第一步:数据准备

1.1 教室表(MBA_Classrooms)

创建教室表,用于管理物理空间:

字段名称字段标识类型说明
教室名称room_name单行文本如:第一阶梯教室、VIP面授室
容纳人数capacity数字用于后期校验是否超载
状态status枚举启用、停用、维护中
创建时间created_at日期时间自动生成
更新时间updated_at日期时间自动更新
在这里插入图片描述

1.2 课表/排课记录表(MBA_Schedules)

创建排课记录表,承载具体的上课时间与资源绑定:

字段名称字段标识类型说明
关联班级rel_class_id关联关系关联MBA_Classes表
关联教师rel_teacher_id关联关系关联MBA_Teachers表
关联教室rel_room_id关联关系关联MBA_Classrooms表
上课日期course_date日期如:2026-04-15
开始时间start_time时间如:09:00
结束时间end_time时间如:11:30
课表状态status枚举待上课、已结课、已取消
创建时间created_at日期时间自动生成
更新时间updated_at日期时间自动更新
在这里插入图片描述

第二步:教室管理页面搭建

2.1 页面整体布局

点击创建页面的图标

在这里插入图片描述

输入页面的名称"教室管理",布局选择管理员布局(基础数据管理通常由管理员维护)

在这里插入图片描述

切换到页面布局,选择管理员布局,添加平级菜单,添加教室管理菜单

在这里插入图片描述

2.2 数据表格配置

在管理员布局的内容插槽下添加布局组件

在这里插入图片描述

修改标题,改为"教室管理"

在这里插入图片描述

在页面布局中添加数据表格组件,数据模型选择教室表

在这里插入图片描述

2.3 配置查询条件

点击筛选器,给表格配置查询条件

添加具体的查询条件:

  • 教室名称(模糊搜索)
  • 状态(下拉选择)
在这里插入图片描述

2.4 配置排序字段

默认按照创建时间的倒序进行排序,最新的教室显示在最前面

在这里插入图片描述

第三步:排课页面布局搭建

3.1 页面整体布局

点击创建页面的图标

在这里插入图片描述

输入页面的名称"排课管理",布局选择教务布局(因为主要是教务人员使用)

在这里插入图片描述

切换到页面布局,选择教务布局,添加平级菜单,添加排课管理菜单

在这里插入图片描述

3.2 数据表格配置

在教务布局的内容插槽下添加布局组件

在这里插入图片描述

修改标题,改为"排课管理"

在这里插入图片描述

在页面布局中添加数据表格组件,数据模型选择课表

在这里插入图片描述

3.3 配置查询条件

点击筛选器,给表格配置查询条件

添加具体的查询条件:

  • 关联班级(关联选择)
  • 关联教师(关联选择)
  • 关联教室(关联选择)
  • 上课日期范围(日期范围)
在这里插入图片描述

3.4 配置排序字段

默认按照上课日期的倒序进行排序,最新的排课显示在最前面

在这里插入图片描述

第四步:排课弹窗实现

在排课管理页面添加弹窗组件,用于录入新的排课

在这里插入图片描述

从组件库中拖拽弹窗组件到页面,设置弹窗标题为"新增排课"

在这里插入图片描述

在弹窗中添加表单容器组件,数据模型选择课表

在这里插入图片描述

修改表单布局,改为双列布局

在这里插入图片描述

选中弹窗组件,关闭显示底部按钮,关闭弹窗默认打开状态

在这里插入图片描述


在这里插入图片描述


给新建按钮配置点击事件,打开弹窗

在这里插入图片描述

第五步:冲突检测与排课提交

创建自定义方法,用来检查排课是否冲突并且提交排课记录

// 提交排课asyncfunctioncheckScheduleConflict(params){const{ teacherId, roomId, classId, courseDate, startTime, endTime }= params;// 计算开始和结束的时间戳(日期毫秒值 + 时间毫秒值)const startTimestamp = courseDate + startTime;const endTimestamp = courseDate + endTime;// 构造核心的时间重叠查询条件: (新开始 < 旧结束) AND (新结束 > 旧开始)const timeOverlapFilter ={$and:[{course_date:{$eq: courseDate }},// 同一天{start_time:{$lt: endTime }},// 新开始时间 < 旧结束时间{end_time:{$gt: startTime }},// 新结束时间 > 旧开始时间{status:{$neq:'3'}}// 排除已取消的课程]};try{// 1. 检测【教师】冲突const teacherRes =await $w.cloud.callDataSource({dataSourceName:'MBA_Schedules',methodName:'wedaGetRecordsV2',params:{filter:{where:{$and:[{rel_teacher_id:{$eq: teacherId }}, timeOverlapFilter ]}},getCount:true}});if(teacherRes.total >0){return{code:-1,msg:'排课失败:该教师在此时间段已有排课安排!'};}// 2. 检测【教室】冲突const roomRes =await $w.cloud.callDataSource({dataSourceName:'MBA_Schedules',methodName:'wedaGetRecordsV2',params:{filter:{where:{$and:[{rel_room_id:{$eq: roomId }}, timeOverlapFilter ]}},getCount:true}});if(roomRes.total >0){return{code:-2,msg:'排课失败:该教室在此时间段已被占用!'};}// 3. 检测【班级】自身的冲突(防止同一班级同一时间排两节不同的课)const classRes =await $w.cloud.callDataSource({dataSourceName:'MBA_Schedules',methodName:'wedaGetRecordsV2',params:{filter:{where:{$and:[{rel_class_id:{$eq: classId }}, timeOverlapFilter ]}},getCount:true}});if(classRes.total >0){return{code:-3,msg:'排课失败:该班级在此时间段已排有课程!'};}// 全部通过,无冲突return{code:0,msg:'校验通过,资源可用'};}catch(error){ console.error('冲突检测失败:', error);return{code:-99,msg:'系统异常,请稍后重试'};}}exportdefaultasyncfunctionsubmitSchedule({ event, data }){// 1. 获取表单数据const formData = $w.form1.value;// 2. 校验时间合法性(course_date、start_time、end_time都是毫秒值)if(formData.start_time >= formData.end_time){ $w.utils.showToast({title:'开始时间必须小于结束时间',icon:'error'});return;} $w.utils.showLoading({title:'正在检测资源冲突...'});try{// 3. 调用前端的冲突检测方法const checkRes =awaitcheckScheduleConflict({teacherId: formData.rel_teacher_id,roomId: formData.rel_room_id,classId: formData.rel_class_id,courseDate: formData.course_date,startTime: formData.start_time,endTime: formData.end_time });// 4. 根据校验结果决定是否入库if(checkRes.code !==0){ $w.utils.hideLoading(); $w.utils.showModal({title:'冲突警告',content: checkRes.msg });return;}// 5. 校验通过,正式写入排课表await $w.cloud.callDataSource({dataSourceName:'MBA_Schedules',methodName:'wedaCreateV2',params:{data:{rel_class_id:{_id: formData.rel_class_id },rel_teacher_id:{_id: formData.rel_teacher_id },rel_room_id:{_id: formData.rel_room_id },course_date: formData.course_date,start_time: formData.start_time,end_time: formData.end_time,status:'1',// 待上课}}}); $w.utils.hideLoading(); $w.utils.showToast({title:'排课成功',icon:'success'}); $w.modal1.close({});// 关闭弹窗 $w.table1.refresh();// 刷新排课列表}catch(error){ $w.utils.hideLoading(); $w.utils.showToast({title:'系统异常',icon:'error'});}}

选择表单容器,修改表单的提交方法,改为我们的自定义方法

在这里插入图片描述


最终效果

教务人员打开排课管理页面,可以看到所有的排课记录:

在这里插入图片描述

点击"新增排课"按钮,打开排课弹窗:

在这里插入图片描述

当试图把张老师同时排给 A 班和 B 班时,系统会立即拦截并弹出:"排课失败:该教师在此时间段已有排课安排!"的警告。

在这里插入图片描述

总结

本节我们完成了排课系统引擎的完整实现:

  1. 数据模型设计
    • 创建了MBA_Classrooms教室表,管理物理空间
    • 创建了MBA_Schedules课表,记录排课信息
  2. 页面搭建
    • 创建排课管理页面,使用教务布局
    • 配置数据表格,显示排课列表
    • 配置查询条件和排序规则
  3. 冲突检测引擎
    • 实现教师冲突检测
    • 实现教室冲突检测
    • 实现班级冲突检测
    • 使用 (Start A < End B) AND (End A > Start B) 算法
  4. 排课提交
    • 时间戳转换与校验
    • 冲突检测调用
    • 排课数据写入

通过本讲的实现,教务人员可以方便地进行排课操作,系统会自动检测并拦截冲突的排课安排。

下一步,我们将继续完善考勤消课机制,实现扫码签到与课时扣减功能。

Read more

基于深度学习YOLOv8 yolov11 yolo26算法的葡萄目标检测与无人机技术的农业水果计数项目 葡萄图像识别第10469期

基于深度学习YOLOv8 yolov11 yolo26算法的葡萄目标检测与无人机技术的农业水果计数项目 葡萄图像识别第10469期

项目中文介绍 该项目是基于YOLO目标检测与无人机技术的农业水果计数项目,核心通过无人机航拍采集果园图像,结合YOLO实时目标检测算法实现果实的精准检测与数量统计,为农业作物管理、产量预估提供数据支撑,以此提升农业生产的效率与智能化水平。 核心功能 1. YOLO实时目标检测:集成YOLO算法实现图像中果实的快速、准确检测,满足农业场景的实时性需求; 2. 无人机图像适配处理:专门针对无人机航拍的图像数据做适配,可直接处理无人机采集的果园影像; 3. 自动化水果计数:基于训练完成的YOLO模型,对检测到的果实进行自动化数量统计,替代人工计数,降低成本、提升效率。 项目结构 ,核心目录与文件如下: * grape_model:葡萄果实检测专用模型目录,内含数据集、训练模型、运行脚本、配置文件等完整子模块,也是项目最新更新的模块; * README.md:项目说明文档,包含概述、功能、使用方法等核心信息。 往期热门主题 主页搜两字"关键词"直达 代码数据获取: 获取方式:***文章底部卡片扫码获取*** . 覆盖了YOLO相关项目、

Uniapp+Vue3 使用父传子方法实现自定义tabBar

一、流程介绍 代码编写顺序 * 第一步:pages.json配置tabbar并配置custom配置项 * 第二步:编写自定义tabbar组件的静态代码(最好使用v-for去写,仿照原生tabbar逻辑) * 第三步:各tabbar页面调用tabbar组件,并传入tabbar索引值 * 第四步:tabbar组件接受传入的值,通过传入索引值判断高亮对象,点击另外的tabbar图标时跳转到相应页面 页面执行顺序 * 第一步:跳转到新的tabbar页面,该组件中的数据重置 * 第二步:tabbar页面向组件传入索引并保存在currentIndex中 * 第三步:v-show判断相应tabbar图标高亮 * 第四步:点击新的tabbar,执行handleItemClick操作,跳转到新的tabbar页面(回到第一步) 二、代码 在page.json中定义tabbar 在page.json中定义tabbar并将custom设置为true 启用自定义tabbar的配置,可以将默认的tabbar隐藏 仍然使用uniapp默认的tabbar定义方式是为了防止跳转过程

Comsol 等离子体仿真:Ar 棒板粗通道流注放电探秘

Comsol 等离子体仿真:Ar 棒板粗通道流注放电探秘

Comsol等离子体仿真,Ar棒板粗通道流注放电。 电子密度,电子温度,电场强度等。 5.5,6.0版本。 在等离子体研究领域,通过 Comsol 进行仿真能为我们揭示许多物理现象背后的奥秘。今天就来聊聊利用 Comsol 5.5 与 6.0 版本,针对 Ar 棒板粗通道流注放电的相关仿真,这里面涉及到电子密度、电子温度以及电场强度等关键参数的分析。 Comsol 版本的选择与优势 Comsol 5.5 和 6.0 版本在等离子体仿真方面各有千秋。5.5 版本已经拥有较为成熟的模块和算法,能稳定地对物理场进行模拟。而 6.0 版本在界面交互、模型构建以及求解器的效率上都有一定提升。例如在构建 Ar 棒板粗通道流注放电模型时,6.0 版本更直观的图形化界面能让我们更快速地定义几何结构和边界条件。

FPGA 和 IC,哪个前景更好?怎么选?

FPGA 和 IC,哪个前景更好?怎么选?

这几年,经常有人来问我: “老师,我是做 FPGA 的,要不要转 IC?” “FPGA 是不是天花板低?” “IC 听起来更高端,是不是更有前景?” 这个问题,本质不是技术问题,而是路径问题。 今天我们把这两个方向掰开讲清楚。 —— 01 先讲定位 如果把整个芯片产业链拆开来看,大致是: 架构 → RTL → 前端验证 → 后端实现 → 流片 → 封测 → 量产 IC 属于“芯片最终形态”,FPGA 属于“可重构硬件平台”。 IC 的目标,是做出一颗定制化、极致性能、极致功耗、极致成本的芯片。 FPGA 的目标,是用可编程逻辑,在无需流片的前提下,实现接近硬件级别的性能。 两者不是上下级关系,而是不同阶段、不同诉求下的解决方案。 很多真正量产前的芯片项目,都会先在