基于微信小程序的教室管理系统_北邮信通院大二下程序设计综合实验

1、项目背景

1.1需求分析

和团委老师交流时得知,目前学校使用的教室管理(预约)系统使用比较繁琐。于是希望制作一款简单易用的教室预约管理系统。

1.2项目要求

1.教室/场地空闲情况的查看。
2.学生提交对于空闲教室/场地的预约申请。
3.老师审批对于空闲教室/场地的预约申请。
4.当老师提交预约申请时,若教室/场地未被占用则申请自动通过。

1.3设计思路

学生端:

1.学生用户预约教室/场地时从微信小程序页面提交姓名、学号以及需要预约的教室/场地编号、用途和待审批老师的工号。
2.微信小程序与数据库建立连接,服务器将请求数据存入数据库表格,将预约目的发送给对应工号的老师,返回教室/场地状态。
3.小程序通过url获取数据库信息,用户得知是否预约成功。

教师端:

1.老师用户预约教室/场地时从微信小程序页面提交姓名、工号以及需要预约的教室/场地。
2.微信小程序微信小程序与数据库建立连接,服务器将请求数据存入数据库表格,检验此时制定教室/场地的使用状态,若未被占用,则数据库向小程序发送申请通过的数据,完成预约。

1.4系统特点

系统具有实时性、可靠性,且方便快捷;学生和教师的权限不同,学生和老师都能查看教室/场地空闲情况和提交预约申请,教师有权对学生提交的预约申请进行审批。

2、成果展示

基于微信小程序的教室管理系统

3、具体实现

3.1前端

数据存储:在这里插入图片描述

小程序首页效果图:
在这里插入图片描述

index.wxml

<view class="first_line">
  <view class="searchbox">
    <input placeholder="请输入" bindinput="getInput" value="{{search_val}}"></input>
    <icon type="cancel" bindtap="now_cancel" color="grey" size="30" wx:if="{{isCancel}}"></icon>
    <view class="btn blue" wx:if="{{isSearch}}" bindtap="now_search">
      <text>搜索</text>
    </view>
  </view>
</view>

<view>
  <text>预约空间:</text>
</view>

<view class="hengxiang_button">
  <view class="long_button">
    <text>教室:</text>
  </view>
  <view class=long_button">
    <navigator url="../building_N/building_N">
      <text>N</text>
    </navigator>
  </view>
  <view class="long_button">
    <text bindtap="click_NULL">S</text>
  </view>
  <view class="long_button">
    <text bindtap="click_NULL">s1楼</text>
  </view>
  <view class="long_button">
    <text bindtap="click_NULL">s2楼</text>
  </view>
  <view class=long_button">
    <text bindtap="click_NULL">s3楼</text>
  </view>
</view>

<view class="tab"></view>

<view class='fenlei'>
  <text>周次</text>
  <!-- 下拉框 -->
    <view class='select_box'>
      <view class='select' catchtap='selectTaps1'>
        <text class='select_text'>{{selectDatas1[indexs1]}}</text>
        <!-- <image class='words_img' src='../../images/sanjiao.png'></image> -->
        <image class='select_img {{shows1&&"select_img_rotate"}}' src='../../icons/倒三角形.png'></image>
      </view>
      <view class='option_box' style='height:{{shows1?(selectDatas1.length>5?300:selectDatas1.length*60):0}}rpx;'>
        <text class='option' style='{{indexs1==selectDatas1.length-1&&"border:0;"}}' wx:for='{{selectDatas1}}' wx:key='this' data-index='{{index}}' catchtap='optionTaps1'>{{item}}</text>
      </view>
    </view>
</view>

<view class="tab"></view>

<view class='fenlei'>
  <text>星期</text>
  <!-- 下拉框 -->
    <view class='select_box'>
      <view class='select' catchtap='selectTaps2'>
        <text class='select_text'>星期{{selectDatas2[indexs2]}}</text>
        <!-- <image class='words_img' src='../../images/sanjiao.png'></image> -->
        <image class='select_img {{shows2&&"select_img_rotate"}}' src='../../icons/倒三角形.png'></image>
      </view>
      <view class='option_box' style='height:{{shows2?(selectDatas2.length>5?300:selectDatas2.length*60):0}}rpx;'>
        <text class='option' style='{{indexs2==selectDatas2.length-1&&"border:0;"}}' wx:for='{{selectDatas2}}' wx:key='this' data-index='{{index}}' catchtap='optionTaps2'>星期{{item}}</text>
      </view>
    </view>
</view>

<view class="tab"></view>

<view class='fenlei'>
  <text>节次</text>
  <!-- 下拉框 -->
    <view class='select_box'>
      <view class='select' catchtap='selectTaps3'>
        <text class='select_text'>{{selectDatas3[indexs3]}}节课</text>
        <!-- <image class='words_img' src='../../images/sanjiao.png'></image> -->
        <image class='select_img {{shows3&&"select_img_rotate"}}' src='../../icons/倒三角形.png'></image>
      </view>
      <view class='option_box' style='height:{{shows3?(selectDatas3.length>5?300:selectDatas3.length*60):0}}rpx;'>
        <text class='option' style='{{indexs3==selectDatas3.length-1&&"border:0;"}}' wx:for='{{selectDatas3}}' wx:key='this' data-index='{{index}}' catchtap='optionTaps3'>{{item}}节课</text>
      </view>
    </view>
</view>

<view class="btn blue" bindtap="now_search_time">
  <text>搜索</text>
</view>

<view class="tab"></view>

index.wxss

.first_line{
  display: flex;
  justify-content: center;
}

.tab{
  display: flex;
  height: 10rpx;
}

.searchbox{
  display: flex;
  flex-direction: row;
  border:1px solid #fc86ad;
  border-radius: 20px;
  width: max-content;
  height:43px;
  align-items: center;
}
input{
  margin-left: 12px;
  font-size: 20px;
  width:150px;
}

.btn {
  display: inline-block;
  margin: 1px;
  padding: 0.7em 1em;
  background:transparent;
  border: 1px;
  border-radius: 20px;
  font-weight: 200;
  text-align: center;
  box-shadow: 2px 2px 4px #aaa,0px 1px 2px #fc86ad;
}
.btn text {
  background: -webkit-linear-gradient(left, #aaa, #fc86ad);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.hengxiang_button{
  flex-direction: column;
  justify-self: center;
  width: auto;
}
.long_button{
  display: inline-flex;
  margin: 1px;
  padding: 0.7em 1em;
  background:transparent;
  border: 1px;
  border-radius: 20px;
  font-weight: 200;
  text-align: center;
  box-shadow: 1px 2px 8px #aaa,1px 1px 2px #fc86ad;
}

.tab{
  display: flex;
  height: 30rpx;
}
.fenlei{
  margin: 0 25rpx;
  height: 90rpx;
  line-height: 90rpx;
  border-bottom: 1rpx solid #e6e6e6;
  display: flex;
  align-items: center;
}
.fenlei text{
  font-size: 30rpx;
  color: #999999;
  margin-left: 15rpx;
}
/* 下拉框 */
.select_box {
  background: #fff;
  width: 620rpx;
  /* margin: 0 auto; */
  height: 90rpx;
  line-height: 90rpx;
  text-align: left;
  position: relative;
}

.select {
  box-sizing: border-box;
  width: 100%;
  height: 86rpx;
  /* border: 1px solid #efefef; */
  border-radius: 8rpx;
  display: flex;
  align-items: center;
  padding: 0 20rpx;
}

.select_text {
  font-size: 28rpx;
  flex: 1;
  color: rgb(102, 102, 102);
  line-height: 86rpx;
  height: 86rpx;
}

.select_img {
  width: 40rpx;
  height: 40rpx;
  display: block;
  transition: transform 0.3s;
}

.select_img_rotate {
  transform: rotate(180deg);
}

.option_box {
  position: absolute;
  top: 86rpx;
  width: 100%;
  /* border: 1px solid #efefef; */
  box-sizing: border-box;
  height: 0;
  overflow-y: auto;
  border-top: 0;
  background: #fff;
  transition: height 0.3s;
  z-index: 100;
}

.option {
  display: block;
  line-height: 40rpx;
  font-size: 28rpx;
  border-bottom: 1px solid #efefef;
  padding: 10rpx;
  color: rgb(102, 102, 102);
}

index.js

Page({
  data: {
    isSearch:false,
    isCancel:false,
    search_val:'',
    /*学生数组 */
    StudentID:[],
    StudentName:[],
    StudentPassword:[],

    shows1:false, //控制下拉列表的显示隐藏,false隐藏、true显示
    shows2:false,
    shows3:false,
    selectDatas1: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], //下拉列表的数据
    selectDatas2: [1,2,3,4,5,6,7],
    selectDatas3: [1,2,3,4,5,6,7,8,9,10],
    indexs1: 0, //选择的下拉列 表下标,
    indexs2: 0,
    indexs3: 0,

    Weeks:'',
    Weekdays:'',
    Times:'',

  },
 
  getInput:function(e)
  {
    //获取搜索框输入的内容
    this.setData({
      search_val:e.detail.value,
    })
    //将搜索内容存入缓存
    wx.setStorageSync(
      "search_room",e.detail.value
    ); 
    if(this.data.search_val.length>0){
      this.setData({
        isSearch:true,
        isCancel:true,
      })
    }else{
      this.setData({
        isSearch:false,
        isCancel:false,
    })
    }
  },
  click_NULL:function(){
    wx.showModal({
      title: '功能尚未开发',
      content: '敬请期待!',
      success: function (res) {
        if (res.confirm) {
          // console.log('用户点击确定')
          wx.removeStorageSync(Object);
          //页面跳转
          wx.redirectTo({
            url: '../index/index',
          })
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
   })
  },
  now_search:function()
  {
   wx.showModal({
      title: '功能尚未开发',
      content: '敬请期待!',
      success: function (res) {
        if (res.confirm) {
          // console.log('用户点击确定')
          wx.removeStorageSync(Object);
          //页面跳转
          wx.redirectTo({
            url: '../index/index',
          })
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
   })
    this.setData({
      
      isSearch:true,
      isCancel:true,
    })
  },
  now_cancel:function()
  {
    this.setData({
      search_val:'',
      isSearch:false,
      isCancel:false,
    })
  },

  // 点击下拉显示框
  selectTaps1() {
    this.setData({
      shows1: !this.data.shows1,
    });
  },
  selectTaps2() {
    this.setData({
      shows2: !this.data.shows2,
    });
  },
  selectTaps3() {
    this.setData({
      shows3: !this.data.shows3,
    });
  },
  // 点击下拉列表
  optionTaps1(e) {
    let Indexs = e.currentTarget.dataset.index; //获取点击的下拉列表的下标
    console.log(Indexs)
    this.setData({
      indexs1: Indexs,
      shows1: !this.data.shows1,
      Weeks:Indexs+1,
    });
    wx.setStorageSync('Weeks', Indexs+1);
  },
  optionTaps2(e) {
    let Indexs = e.currentTarget.dataset.index; //获取点击的下拉列表的下标
    console.log(Indexs)
    this.setData({
      indexs2: Indexs,
      shows2: !this.data.shows2,
      Weekdays:Indexs+1,
    });
    wx.setStorageSync('Weekdays', Indexs+1);
  },
  optionTaps3(e) {
    let Indexs = e.currentTarget.dataset.index; //获取点击的下拉列表的下标
    console.log(Indexs)
    this.setData({
      indexs3: Indexs,
      shows3: !this.data.shows3,
      Times:Indexs+1,
    });
    wx.setStorageSync('Times', Indexs+1);
  },
  now_search_time(){
    wx.request({
      url: 'https://abc.charlieqyq.top:29999/RoomQuery.php',
      data:{
        'Weeks':this.data.Weeks,
        'Weekdays':this.data.Weekdays,
        'Times':this.data.Times,
      },
      success:function(res)
      {
        console.log(res.data)
        //将教室情况存入缓存
        wx.setStorage({
          data: res.data,
          key: 'roominfo',
        })
        wx.navigateTo({
          url: '../search_result/search_result',
        })
      }     
    })   
  },

  /*页面开始加载,就会触发的生命周期事件*/ 
  onLoad: function (options) {
  }
})

index.json

{
  "enablePullDownRefresh":true,
  "navigationBarBackgroundColor": "#fc86ad",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "教室管理系统(学生版)",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light"
}

完整前端代码已上传GitHub,点击跳转

3.2后端

服务器详细配置如下:
内核版本:Linux 5.4.73-1-pve #1 SMP PVE 5.4.73-1
PVE管理器:pve-manager/6.3-2/22f57405
CPU:16x Intel® Xeon® CPU E5-2630L v3
内存:16G(8Gx2)
虚拟机详细配置如下:
虚拟机分配:2 Core,2048M RAM,10GB硬盘
虚拟机系统:Ubuntu 20.04.2 LTS(Py3.7.9)
虚拟机平台:宝塔面板 免费版 7.5.1
虚拟机软件:Apache 2.4.46,MySQL 5.7.33,PHP-5.6,phpMyAdmin 4.4
所用软件:
在这里插入图片描述
数据库设计:
在这里插入图片描述
在这里插入图片描述
接口设计:

接口名称功能
Update.php修改对应申请编号的申请记录
RoomQuery.php查询所选节次、星期、周次可用的教室
Approval.php审批对应申请编号的申请记录
AppliQuery.php查询申请ID对应的所有申请记录
TeacherQuery.php查询审批教师为ID的所有申请记录
ApplicationUpload.php提交申请信息
TeacherLogin.php验证教师工号和登录密码是否正确
StudentLogin.php验证学生学号和登录密码是否正确

by我的好队友qy,点击跳转Github查看源码

  • 2
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yumenai_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值