基于微信小程序的实验室预约系统的设计与开发

个人介绍

hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述
🦁作者简介:一名喜欢分享和记录学习的在校大学生
💥个人主页:code袁
💥 个人QQ:2647996100
🐯 个人wechat:code8896

专栏导航

code袁系列专栏导航
1.毕业设计与课程设计:本专栏分享一些毕业设计的源码以及项目成果。🥰🥰🥰
2.微信小程序开发:本专栏从基础到入门的一系开发流程,并且分享了自己在开发中遇到的一系列问题。🤹🤹🤹
3.vue开发系列全程线路:本专栏分享自己的vue的学习历程。

非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨ 

在这里插入图片描述

文章目录

        • 个人介绍
        • 专栏导航
        • 1、前言介绍
        • 2、开发技术简介
        • 3、系统功能图
        • 4、功能实现
        • 5、库表设计
        • 6、性能测试
        • 7、关键代码
        • 8、源码获取
      • 🎉写在最后

1、前言介绍

伴随着信息技术与互联网技术的不断发展,校园也进到了一个新的信息化时代,传统管理技术性没法高效率、容易地管理体育场预约信息内容。为了实现时代的发展必须,提升实验室预约高效率,各种各样实验室预约体系应时而生,实验室预约管理系统的实现是信息内容时代浪潮时代的产物之一。一切系统都要遵循系统设计的基本流程。它还需要通过市场调查、需求分析报告、汇总设计、详尽设计以及测试,根据Node语言表达设计,完成实验室预约管理系统。该系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Node技术,前端采用uniapp微信小程序等技术实现,选用MySQL作为数据库。
本实验室预约管理系统采用前后端分离的方式来实现,前端Vue、Element组件编写前端代码为主、其特点可以实时渲染加载数据,不用像以前传统的页面,写完要重新启动项目才能加载数据。系统还采用的File文件组件上传和预览图片等,以及前端利用了第三方富文本编辑器框架技术实现了实验室详情介绍和系统公告等模块。这样比传统文本框只能填写文字又来更好更直观的页面呈现方式。不仅可以上传文字,还可以直接复制网页图片文字等。实现动态渲染页面样式和内容等。

2、开发技术简介

本节介绍场馆预约平台用到的一些技术和开发环境的简介,用到开发技术主要包括:
(1)前端用到Element UI组件库、Vue框架和微信小程序
(2)后端用到Node
(3)包管理器Npm
(4)中间件Express
(5)数据库MySQL
系统开发环境主要是:前端开发工具Vscode,Hbuilder、操作系统Win10、CPU i5-9300H、内存8G。
在这里插入图片描述

3、系统功能图

实验室预约系统主要由客户端(微信小程序和安卓手机App)和Web管理端(基于Web服务器Apache Tomcat,MySQL数据库)这两个子系统组成。这两个子系统之间通过Htpp的request请求和response响应以json形式的数据交互,共同实现了实验室预约平台的功能。
客户服务端主要包括三大主要的功能模块:登录、预约和扫码签到模块。Web管理端主要包括三大主要的功能模块:用户、动态和预约模块。这六大模块还有相应的子模块,通过对子模块的实现来实现整个客户端的功能。如图4-3所示。

在这里插入图片描述

4、功能实现

系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。下图就是管理员登录页面。
在这里插入图片描述

该界面实现对实验室的添加、删除、修改等一系列功能

在这里插入图片描述

该界面实现对实验室的动态的添加、删除、修改等一系列操作

在这里插入图片描述
在这里插入图片描述

实验室预约的流程:当用户选择自己需要的预约的项目后,则需要用户选择合法的日期并且本系统的合法日期为当前日期的下一天的六天合法日期。当用户进入预约详情页面时用户可以选择预约的时间和地点。预约按钮点击后会判断用户是否登录以及是否重复预约等。若预约信息合法则同request的库生成对应订单的二维码并将预约信息存入到数据库中

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、库表设计

程序设计是离不开对应数据库的设计操作的,这样的做法就是减少数据对程序的依赖性,所以数据库的设计也是需要花费大量的日常时间来进行设计的,在设计中对程序开发需要存储的数据信息进行实体划分,先确认实体,然后设计实体的属性等操作,这种设计就是数据库设计里面不能少的必须有的E-R模型设计。为了降低程序设计的对应的数据库设计难度,开发人员也可以使用相应的工具来进行E-R模型设计,现在市面上设计E-R模型的工具有PowerDesigner建模工具,Navicat制作工具,还有微软的Visio绘图工具。为了简便起见,本程序在设计E-R模型的时候,就选用了微软的Visio这款功能强大,操作便利的绘图工具。

1.预约实体及其附属图

在这里插入图片描述
2.管理员实体及其附属图

在这里插入图片描述
3.实验室实体及其附属图

在这里插入图片描述

6、性能测试

单元测试是软件开发中的一种测试方法,用于测试代码中的最小可测试单元(通常是函数或方法),以验证其行为是否符合预期[15]。单元测试可以检测代码中的缺陷和错误,及时发现和修复代码问题,提高代码的质量和稳定性,也可以帮助开发人员快速定位问题,并提供反馈和调试信息,提高开发效率和效果。总之,单元测试是软件开发中非常重要的一环,可以帮助开发人员提高代码质量和效率,提高软件产品的质量和稳定性。

1.from base.data_read import ReadData
2.from base.response import method_post
3.import pytest

4.# ====测试数据读取====
5.def data_read():
6.    # 1. 将yaml文件读取
7.    data_dict = ReadData('data.yaml').read_data()
8.    # 2. 从字典中取数据  url  accounts
9.    url = data_dict['test_user_login']['url']
10.    accounts = data_dict['test_user_login']['accounts']
11.    # 3. 返回数据 供测试用例调用
12.    return url, accounts
13.
14.
15.class TestLogin():
16.    @pytest.mark.parametrize('url', [data_read()[0]])
17.    @pytest.mark.parametrize('accounts', data_read()[1])
18.    def test_login(self, url, accounts):
19.        # 1. 注意这里的account是列表格式
20.        print('\n>>>', type(accounts))
21.        print(accounts)
22.        # 2. 发请求
23.        response = method_post(url, json=accounts)
24.        # 3. 判断是否请求成功
25.        assert response.status_code == 200
26.        # 4. 根据返回的code判断是否登录成功
27.        code = response.json().get('code')
28.        print(response.json())
29.        assert code == 0, '登录失败!'
30.# =============测试结果==============
31.========= 1 failed, 1 passed in 11.81s ==========
7、关键代码
//index.js
//获取应用实例
const app = getApp()
const {login} =require('../../api/login')
Page({
  data: {
    phone: '',
    password: '',
    clientHeight:'',
    array: ['学生', '教师', ],
    index: 0,
  },
  onLoad(){
    var that=this
    wx.getSystemInfo({ 
      success: function (res) { 
        console.log(res.windowHeight)
          that.setData({ 
              clientHeight:res.windowHeight
        }); 
      } 
    }) 
  },
  bindType: function (e) {
    this.setData({
      index: e.detail.value
});
  },
  //协议
  goxieyi(){
   wx.navigateTo({
     url: '/pages/oppoint/oppoint',
   })
  },
  //获取输入款内容
  phone(e){
   this.setData({
     phone:e.detail.value
   })
  },
  password(e){
    this.setData({
      password:e.detail.value
    })
  },
  //登录事件
  goadmin(){
    let flag = false  //表示账户是否存在,false为初始值
    if(this.data.phone=='')
    {
      wx.showToast({
        icon:'none',
        title: '账号不能为空',
      })
    }else if(this.data.password==''){
      wx.showToast({
        icon:'none',
        title: '密码不能为空',
      })
    }else{
      let data={
        phone:this.data.phone,
        password:this.data.password,
        isadmin:this.data.index
      }
     login(data).then(res=>{
       console.log('55',res.data[0])
       wx.setStorageSync('userInfo', res.data[0])
       //添加登录状态
       wx.setStorageSync('statusLogin', true)
       wx.showToast({
        title: res.msg,
        icon:'none'
      })
       if(res.msg=="登录成功"){
        wx.switchTab({
            url: '../my/my',
          })
       }
     })
    }
  },
  register(){
    wx.navigateTo({
      url: './register',
    })
  }
})
 

<template>
  <div class="messge">
    <el-dialog title="提示" :visible.sync="dialogVisible" width="40%">
      <!-- 弹窗信息 -->
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        :inline="true"
        :before-close="handleClose"
        label-width="80px"
      >
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" placeholder="实验室名称"></el-input>
        </el-form-item>
        <el-form-item label="开放时间" prop="openTime">
          <el-input
            v-model="form.openTime"
            placeholder="实验室开发时间"
          ></el-input>
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input v-model="form.address" placeholder="实验室地址"></el-input>
        </el-form-item>
        <el-form-item label="简介" prop="desc">
          <el-input v-model="form.desc" placeholder="实验室简介"></el-input>
        </el-form-item>
        <el-form-item label="负责人" prop="id">
          <el-select v-model="form.adminId" placeholder="请选择">
            <span></span>
            <el-option
              v-for="item in options"
              :key="item.id"
              :label="item.username"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="实验室logo">
          <commonUpload></commonUpload>
        </el-form-item>
      </el-form>
      <!-- 表单提交 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancle">取 消</el-button>
        <el-button type="primary" @click="submit">确 定</el-button>
      </span>
    </el-dialog>

    <div class="manage-hander">
      <!-- 添加按钮 -->
      <el-button type="primary" @click="handleAdd">+ 新增</el-button>
    </div>
    <!-- 表格 -->
    <div class="common-table">
      <el-table :data="tableData" stripe height="90%" style="width: 100%">
        <el-table-column prop="name" label="实验室名称"> </el-table-column>
        <el-table-column prop="openTime" label="实验室开放时间">
        </el-table-column>
        <el-table-column prop="address" label="实验室地址"> </el-table-column>
        <el-table-column prop="logo" label="logo">
          <template slot-scope="scope">
            <el-image
              style="width: 150px; height: 100px"
              :src="scope.row.logo"
              :preview-src-list="[scope.row.logo]"
            >
            </el-image>
          </template>
        </el-table-column>
        <el-form-item label="简介" prop="desc">
          <el-input v-model="form.desc" placeholder="实验室简介"></el-input>
        </el-form-item>
        <el-table-column label="负责人" prop="adminId">
          <template slot-scope="scope">
            <span v-for="item in options" :key="item.id">
              <span v-if="scope.row.adminId === item.id">
                {{ item.username }}
              </span>
            </span>
          </template>
        </el-table-column>
        <el-table-column prop="addr" label="操作">
          <template slot-scope="scope">
            <el-button
              type="primary "
              size="mini"
              @click="handleEdit(scope.row)"
              >编辑</el-button
            >
            <el-button
              type="danger"
              size="mini"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页组件 -->
      <el-pagination
        class="page"
        layout="prev, pager, next"
        :total="total"
        @current-change="handlePage"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import commonUpload from "@/components/commonUpload.vue";
import { getPlace, addPlace, deletePlace, updatePlace } from "@/api/index";
import { allAdmin } from "@/api/reservation";
export default {
  name: "User",
  data() {
    return {
      dialogVisible: false,
      // 表单字段
      form: {
        name: "",
        openTime: "",
        address: "",
        logo: "",
        adminId: "",
        desc: "",
      },
      // 表單校驗
      rules: {
        name: [{ required: true, message: "请输入实验室名称" }],
        openTime: [{ required: true, message: "请输入实验室开发时间" }],
        address: [{ required: true, message: "请输入实验室地址" }],
        desc: [{ required: true, message: "请输入实验室简介" }],
      },
      options: [
        {
          id: "",
          username: "",
        },
      ],
      // 表单数据
      tableData: [],
      total: 0, //页面的总条数
      modelType: 0, //0表示是新增的弹窗 ,1表示的是编辑
      userFrom: {
        username: "",
      },
    };
  },
  components: {
    commonUpload,
  },
  methods: {
    // 提交
    submit() {
      if (this.modelType == 0) {
        this.$refs.form.validate((value) => {
          // 校验为真
          if (value) {
            console.log("value", this.form);
            this.form.logo = this.$store.state.upload.imgUrl;
            addPlace(this.form).then((res) => {
              // console.log(res);
              this.$message.success("添加成功");
            });
            this.$refs.form.resetFields();
            this.dialogVisible = false;
            this.getList();
          }
        });
      } else {
        this.$refs.form.validate((value) => {
          // 校验为真
          if (value) {
            console.log("value", this.form);
            updatePlace(this.form).then((res) => {
              // console.log(res);
              this.$message.success("修改成功");
            });
            this.$refs.form.resetFields();
            this.dialogVisible = false;
            this.getList();
          }
        });
      }
    },
    handle(e) {
      console.log();
      // let id = res.id;
      this.$confirm("要修改用户权限吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then((res) => {
        privalUser(e).then((res1) => {
          console.log(res1.data.data);
          this.$message.success(res1.data.data.msg);
        });
      });
    },
    // 关闭弹窗
    handleClose() {
      this.$refs.form.resetFields();
      this.dialogVisible = false;
    },
    // 点击取消按钮
    cancle() {
      this.handleClose();
    },
    // 表单的编辑
    handleEdit(res) {
      this.modelType = 1;
      this.dialogVisible = true;
      // 注意到对当前的数据进行深度拷贝
      this.form = JSON.parse(JSON.stringify(res));
    },
    //表单的删除
    handleDelete(res) {
      // let id = res.id;
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 调用删除接口
          var that = this;
          deletePlace(res).then((res) => {
            that.$message({
              type: "success",
              message: res.data.data.msg,
            });
          });
          this.getList();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    // 新增数
    handleAdd() {
      (this.modelType = 0), (this.dialogVisible = true);
      this.form = {};
    },
    getOpstions() {
      allAdmin().then((res) => {
        this.options = res.data.data.data;
      });
    },
    // 查询数据
    handleSearch() {
      searchUser(this.userFrom).then((res) => {
        console.log(res.data.data);
        this.tableData = res.data.data.data;
        // this.getList();
      });
    },
    //分页
    handlePage(val) {
      console.log(val);
    },
    // 获取数据
    getList() {
      // 采用封装的api接口方法
      getPlace().then((res) => {
        console.log("11", res.data.data.data);
        this.tableData = res.data.data.data;
      });
    },
  },
  // 挂载
  mounted() {
    this.getList();
    this.getOpstions();
  },
};
</script>

<style lang="less">
.messge {
  height: 90%;
  .common-table {
    position: relative;
    height: calc(100% - 62px);
    .page {
      position: absolute;
      bottom: 0;
      right: 20px;
    }
  }
  .manage-hander {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}
.el-table .cell {
  img {
    height: 50rpx;
  }
}
</style>

8、源码获取

大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

🎉写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star ✨支持一下哦!手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518605.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c语言文件操作(超详细)

前言 这次的博客&#xff0c;可以让大家快速掌握文件操作&#xff0c;方便大家快速找到不懂的内容 文件操作的作用以及基础 1. 为什么使用文件&#xff1f; 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&…

(arxiv2401) CrossMAE

作者团队来自加州大学伯克利分校&#xff08;UC Berkeley&#xff09;和加州大学旧金山分校&#xff08;UCSF&#xff09;。论文主要探讨了在MAE的解码中&#xff0c;图像patch之间的依赖性&#xff0c;并提出了一种新的预训练框架 CrossMAE。 论文的主要贡献包括&#xff1a; …

代码随想录-算法训练营day02【滑动窗口、螺旋矩阵】

专栏笔记&#xff1a;https://blog.csdn.net/weixin_44949135/category_10335122.html https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG?uc71ed002e4554fee8c262b2a4a4935d8977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II &#xff0c;总结 建议…

(源码+部署+讲解)基于Spring Boot和Vue的大学生快递代取服务平台的设计与实现

一、引言 本报告旨在详细阐述基于Spring Boot后端框架和Vue前端框架的大学生快递代取服务平台的设计与实现过程。该平台旨在为大学生提供便捷的快递代取服务&#xff0c;解决因时间冲突或距离过远而无法及时取件的问题。通过该平台&#xff0c;用户可以发布代取需求&#xff0c…

[中级]软考_软件设计_计算机组成与体系结构_07_存储系统

存储系统 层次划存储概念图局促性原理分类存储器位置存取方式按内容存储按地址存储 工作方式拓展 往年真题 高速缓存(cache)概念案例解析&#xff1a;求取平均时间 Cache与主存的地址映射映像往年真题 主存编制计算编址大小的求取编址与计算存储单元编址内容总容量求取例题解析…

java爬虫入门程序

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version> </dependency><!-- 爬虫需…

github生成新的SSH密钥

首先是参考官方文档 生成新的 SSH 密钥并将其添加到 ssh-agent述 当你在创建SSH密钥时遇到提示&#xff1a; Enter file in which to save the key (/c/Users/YOU/.ssh/id_ALGORITHM):这一步是让你选择保存生成的SSH密钥对的文件名和位置。如果你直接按回车键&#xff08;[Pr…

Java项目:基于Springboot+vue实现的医院住院管理系统设计与实现(源码+数据库+开题报告+任务书+毕业论文)

一、项目简介 本项目是一套基于Springbootvue实现的医院住院管理系统设 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简…

Activity入门2——生命周期与任务栈

OnCreate与OnDestroy OnCreate&#xff1a;创建一个活动。 OnDestroy&#xff1a;销毁一个活动。 假设某个用户在一个活动里输入了一些信息&#xff0c;用户由于某些原因退出了该活动&#xff0c;返回时希望能够还原之前输入的信息&#xff0c;不然重新输入就太麻烦了。 pub…

软考高级架构师:嵌入式软件开发概念和例题

一、AI 讲解 嵌入式软件开发和传统软件开发的差异 嵌入式软件开发与传统软件开发在目标、环境和开发过程等方面有显著的差异。下面通过对比的方式&#xff0c;简要阐述这些差异所在&#xff1a; 特性嵌入式软件开发传统软件开发开发目标针对特定硬件系统&#xff0c;强调软硬…

【Fn+windows键】‘Windows键+L’不能锁屏的问题

winL锁屏 3个键盘灯1.NumLock指示灯2.CapsLock指示灯3.ScrollLock指示灯 2.电脑锁屏问题 突然发现winL不能锁屏&#xff0c;反而是在自己打开的软件界面内编辑 各种操作之下&#xff0c;发现键盘上最不常用的灯亮了 所以了解了一番键盘灯的功能 3个键盘灯 1.NumLock指示灯 N…

快递费用一目了然:taobao.item_fee API在电商中的应用

taobao.item_fee API在电商中的应用主要体现在精准计算快递费用&#xff0c;从而为用户提供一个更加透明和便捷的购物体验。这一接口允许淘宝或天猫的开发者根据商品ID、收货地址等信息&#xff0c;精确计算商品的快递费用。对于用户而言&#xff0c;这意味着在购物过程中能够实…

工厂模式图

工厂模式 介绍一下简单工厂模式与工厂方法模式 结构图 简单工厂模式 工厂方法模式

【剑指offr--C/C++】JZ7 重建二叉树

一、题目 二、思路及代码 前序遍历&#xff1a;中、左、右。所以前序遍历的第一个节点是树的根节点&#xff0c;第二个节点是左子树的根节点。。。。 中序遍历&#xff1a;左、中、右。树的根节点在中间某处 我们可以根据二者的特点结合一下&#xff1a;对于前序遍历序列{1,2,4…

ubuntu安装sublime3并设置中文

安装Sublime Text 3 在Ubuntu上安装Sublime Text 3可以通过以下步骤进行&#xff1a; 打开终端。 导入Sublime Text 3的GPG密钥&#xff1a; wget -qO- https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - 添加Sublime Text 3的存储库&#xff1a; …

纯C代码模板

一、快排 void QuickSort(int *a,int left,int right){if(left>right) return;else{int low left,high right;int pivot a[low];while(low<high){while(a[high] > pivot && low < high){high--;}a[low] a[high]; //必须先动a[low]while(a[low] < …

TR3 - Transformer算法详解

目录 文本输入处理词向量位置向量 编码器 EncoderSelf-Attention多头注意力机制残差连接 解码器 Decoder线性层与Softmax损失函数总结与心得体会 这周来看一下Transformer是怎么将文本转换成向量&#xff0c;然后又输入到模型处理并得到最终的输出的。 文本输入处理 词向量 …

计算机内存是如何管理的

计算内存的那些事儿——内存管理 大家回忆一下&#xff0c;计算机结构&#xff0c;或者说一个SoC&#xff08;system-on-chip&#xff09;芯片的结构。 cpu、memory、peripherals&#xff0c;这是计算机的主要部件&#xff0c;三者之间通过system bus勾搭在一起。 The main co…

易支付和独角数卡对接TokenPay开通USDT收款教程

TRX、USDT-TRC20、ETH系列区块链代币的支付通道是很多发卡和电商平台需要的&#xff0c;因为传统的微信、支付宝、PayPal等支付接口审查严格、手续费高。自建的代币接口完成没有手续费&#xff0c;稳定可靠&#xff0c;也没有审查要求。 易支付在行业普及广泛&#xff0c;大部…

JVM(Java虚拟机)

文章目录 一、JVM简介1.1 JVM概念1.2 什么是Java虚拟机呢&#xff1f;Java虚拟机的好处是什么呢&#xff1f; 二、JVM整体组成部分三、类加载器3.1 类加载子系统3.2 类加载过程3.2.1 装载(Load)3.2.2 链接(Link)3.2.3 初始化(Initialize) 四、运行时数据区4.1 方法区&#xff0…