基于Vue、Node和MongDB的医院挂号预约系统

幻世

发布日期: 2021-06-23 20:41:52 浏览量: 213
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

一、概述

1.1 介绍

  • 项目名称:Hs 医院挂号预约系统 / Hs 医院门诊预约挂号系统

  • 项目技术:Vue + Element UI + Node + MongoDB

1.2 目标

在互联网发达的现代,为病人挂号预约提供便利,不用再在医院的挂号窗口排队等待,而是利用互联网的便利;使用本系统,用户可以足不出户、免去等待的进行挂号预约,医院方面的管理员可以便捷的对医院中的一些数据、信息进行存储、管理、维护,节省信息管理的成本。

二、需求分析

2.1 功能需求

用户

  • 病人:可以查看医院信息、科室门诊、医生信息、预约挂号、预约记录

  • 管理员:可以对系统内的数据、信息进行管理

用例

  • 登录、注册、退出登录

  • 查看医院信息、科室门诊信息、医生信息、预约挂号、预约挂号记录

  • 用户管理、科室管理、值班管理、挂号管理(仅管理员)

系统结构图

2.2 非功能需求

  • 简洁:界面简洁、结构明了,没有多余的信息妨碍用户达到目的

  • 快捷:通过页面模块化,提高模块的复用性,减少页面的刷新同时提高页面的加载速度

三、设计

3.1 数据库设计

3.1.1 数据库说明

  • MongoDB 数据库的集合可以看做是 其他关系数据库(如 MySQL)的表

  • 集合的字段 _id 为唯一主键

  • 一些除 _id 外的 ObjectId 数据类型的字段相当于外键

3.1.2 数据结构

用户集合

字段 数据类型 说明
_id ObjectId 每个用户的 id
account String 账户
name String 真实姓名
password String 密码
type String 用户类型
sex String 性别
dcClinic ObjectId 门诊(医生)
phone Number 电话
email String 邮箱
dcinfo String 简介(医生)

科室集合

字段 数据类型 说明
_id ObjectId 每个门诊的 id
department String 科室
clinic String 门诊

挂号预约记录集合

字段 数据类型 说明
_id ObjectId 每个挂号记录的 id
patient ObjectId 预约的用户的 id
doctor ObjectId 被预约的医生
duty String 预约的星期
timeslot String 预约的时间段
appointment Date 预约的日期

医生排班记录集合

字段 数据类型 说明
_id ObjectId 每个排班记录的 id
doctor ObjectId 医生 id
duty String 排班时星期
timeslot String 排班的时间段
number Number 号源数

3.2 接口设计

相关依赖包: Axios、CORS

前端 Axios 设置

  1. import axios from "axios";
  2. const http = axios.create({
  3. baseURL: 'http://localhost:3000/web/api'
  4. })
  5. export default http

后端路由设计

从请求路径中获取需要访问的集合的名称,以实现通用路由,减少代码量。

  1. // server/routes/web/index.js
  2. app.use('/web/api/rest/:resource', async (req, res, next) => {
  3. req.Model = require(`../../models/$ {req.params.resource}`)
  4. next()
  5. }, routes);

3.2.1 登录

地址 rest/user/login
方式 POST
请求参数 账户、密码
返回参数 token
  1. // 查询不到账户:token = ‘user err’
  2. // 密码错误:token = ‘password err’
  3. // 存在账户、密码正确:token = _id.account.(p/d/a) p代表病人、d代表医生、a代表管理员

3.2.2 注册、添加信息

地址 rest/集合名
方式 POST
请求参数 对应集合的必须信息
返回参数 添加结果

3.2.3 查询信息

地址 rest/集合名
方式 GET
请求参数
返回参数 该集合内的所有记录

3.2.4 查询全部病人

地址 rest/user/patient
方式 GET
请求参数
返回参数 user 集合内用户类型为病人的记录

3.2.5 查询全部医生

地址 rest/user/doctor
方式 GET
请求参数
返回参数 user 集合内用户类型为医生的记录

3.2.6 查询某科室下的医生

地址 rest/department/doctor/:id
方式 GET
请求参数 科室 id
返回参数 符合条件的医生用户记录

3.2.7 根据 id 查询

地址 rest/集合名/:id
方式 GET
请求参数 id
返回参数 在该集合内对应 id 的记录

3.2.8 根据病人 id 查询挂号记录

地址 rest/registration/myregistration/:id
方式 GET
请求参数
返回参数 该 id 的用户的挂号记录

3.2.9 根据 id 删除

地址 rest/集合名/:id
方式 DELETE
请求参数 id
返回参数 删除结果

3.2.10 根据 id 编辑

地址 rest/集合名/:id
方式 PUT
请求参数 id
返回参数 编辑结果

3.2.11 根据科室名查询下属门诊

地址 rest/department/clinic/:department
方式 GET
请求参数 科室名称
返回参数 该科室下的门诊记录

3.2.12 根据医生 id 查询排班信息

地址 rest/scheduling/dc/:id
方式 GET
请求参数 id
返回参数 该 id 医生的排班记录

3.3 页面设计

3.3.1 登录、注册页面设计

3.3.2 用户主页设计

3.3.3 用户挂号记录页面

3.3.4 信息列表页

3.3.5 添加信息页

3.3.6 编辑信息页

3.4 功能设计

3.4.1 登录功能

3.4.2 挂号预约功能

3.4.3 管理功能

四、实现

使用前后端分离的开发模式,前端使用 Vue + Element UI 实现模块式的页面设计,使用 Node + Express + Mongoose + MongoDB 实现从数据库获取数据用于与前端交互,前端使用 Axios + CORS 实现向后端接口发送数据、获取数据、实现跨域等。

4.1 后端实现

后端文件目录结构

/index.js

  1. const express = require("express"); // 导入依赖包 express
  2. const app = express();
  3. app.use(require('cors')()) // 使用依赖包 cors 跨域
  4. app.use(express.json())
  5. require('./plugins/db')(app); // 导入 db 模块
  6. require('./routes/web')(app); // 导入 web 模块
  7. app.listen(3000, () => { // 监听端口 3000
  8. console.log('已连接端口3000,http://localhost:3000')
  9. });

/plugins/db.js

  1. module.exports = app => {
  2. const mongoose = require('mongoose'); // 导入依赖包 mongoose
  3. mongoose.connect('mongodb://127.0.0.1:27017/registration-booking-system', {
  4. useNewUrlParser: true // 连接mongodb数据库的 registration-booking-system 数据库
  5. })
  6. }

/models/Department.js:科室集合的模型文件,其他模型文件同理

  1. const mongoose = require('mongoose'); // 导入依赖包 mongoose
  2. const schema = new mongoose.Schema({ // 创建模型
  3. department: { type: String, required: true }, // 科室名称
  4. clinic: { type: String, required: true } // 门诊名称
  5. })
  6. module.exports = mongoose.model('Department', schema) // 导出 Department 的集合模型
  7. /routes/web/index.js
  8. module.exports = app => {
  9. const express = require('express'); // 导入依赖包 express
  10. const routes = express.Router({
  11. mergeParams: true
  12. });
  13. //...此处省略一部分
  14. // 添加
  15. routes.post('/', async (req, res) => {
  16. const model = await req.Model.create(req.body)
  17. res.send(model) // 根据传递过来的数据创建一条记录,然后返回结果
  18. })
  19. //...此处省略一部分
  20. //...
  21. app.use('/web/api/rest/:resource', async (req, res, next) => {
  22. req.Model = require(`../../models/$ {req.params.resource}`)
  23. next() // 通过请求的路径获取要访问的集合,实现通用性
  24. }, routes);
  25. }

4.2 前端实现

前端文件目录结构:

开发环境(未打包)

/http.js

  1. import axios from "axios"; // 导入 axios 依赖
  2. const http = axios.create({
  3. baseURL: 'http://localhost:3000/web/api' // 与后端交互
  4. })
  5. export default http

/main.js

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. import './plugins/element.js' // 使用 element UI
  4. import router from './router' // 使用 vue-router
  5. Vue.config.productionTip = false
  6. import http from "./http"; // 使用 axios
  7. Vue.prototype.$http = http;
  8. new Vue({
  9. router,
  10. render: h => h(App)
  11. }).$mount('#app')

使用 Axios 在前端页面的 vue 组件中获取后端数据

  1. async findall() {
  2. const res = await this.$http.get('rest/user') // 发送请求
  3. this.items = res.data // 获取结果
  4. }

/router/index.js

  1. import Vue from 'vue'
  2. import VueRouter from 'vue-router'
  3. //...
  4. import Login from "@/views/Login";
  5. //...
  6. Vue.use(VueRouter)
  7. const routes = [
  8. //...
  9. { path: '/login', component: Login }, // 路径为 /login 时,加载 Login.vue 组件
  10. //...
  11. ]
  12. const router = new VueRouter({
  13. routes
  14. })
  15. // 通过 token 判断用户权限以及登录状态
  16. router.beforeEach((to, from, next) => {
  17. if (to.path === '/home') {
  18. next()
  19. }
  20. if (to.path === '/admin') {
  21. let token = window.sessionStorage.getItem('token')
  22. if(token === null) {
  23. next('/login')
  24. } else {
  25. const id = token.split('.')[0]
  26. const ut = token.split('.')[2]
  27. if(ut !== 'a') {
  28. next('/login')
  29. }
  30. }
  31. }
  32. next()
  33. })
  34. export default router

使用 vue-router 实现页面跳转

  1. @click="$router.push(`/user/edit/${scope.row._id}`" // 点击事件,触发页面跳转并传递 id

打包后

五、测试

对源码以及打包后都进行了如下的测试。

5.1 登录测试

编号 输入数据 预期输出 实际输出
L01 账户:686868,密码:123 用户名错误 用户名错误
L02 账户:lhz,密码:321 密码错误 密码错误
L03 账户:lhz,密码:123 登录成功,回到首页 登录成功,回到首页
L04 账户:root,密码:123 进入管理后台 进入管理后台

5.2 注册测试

编号 输入数据 预期输出 实际输出
L05 账户:686868,密码:123 注册成功 注册成功

5.3 退出登录测试

编号 输入数据 预期输出 实际输出
L06 登录后点击退出 清除 token 清除 token

5.4 挂号测试

编号 输入数据 预期输出 实际输出
L07 选择已过去日期 提示选择未来的日期 提示选择未来的日期
L08 选择未来的日期 保存成功 保存成功

5.5 取消挂号记录

编号 输入数据 预期输出 实际输出
L09 选择取消挂号记录 询问,确认后清除,取消则无反应 询问,确认后清除,取消则无反应

5.6 添加信息

编号 输入数据 预期输出 实际输出
L10 按正确格式添加 保存成功 保存成功
L11 不按正确格式添加 提示错误,无法保存 提示错误,无法保存

5.7 删除信息

编号 输入数据 预期输出 实际输出
L12 选择删除信息 询问,确认后清除,取消则无反应 询问,确认后清除,取消则无反应

5.8 编辑信息

编号 输入数据 预期输出 实际输出
L13 按正确格式编辑 保存成功 保存成功
L14 不按正确格式编辑 提示错误,无法保存 提示错误,无法保存

六、项目总结

通过这次项目,我对 Vue、Node、JavaScript 的知识有了更近一步的认识与了解,对这些知识的熟悉程度也更近了一步;同时开发项目的过程中,我保持在 Gitee 中使用分支等对项目源码进行存储、备份,因此我对 Git 的操作也更加熟悉。在这次开发中,我使用了一些新的方法与思路,这使我的眼界与思维更加开阔,收获到了许多知识。

上传的附件 cloud_download 《Hs医院挂号预约系统》设计开发文档.docx ( 2.33mb, 2次下载 ) cloud_download registration-booking-system.zip ( 5.13mb, 3次下载 )
error_outline 下载需要10点积分

发送私信

1
文章数
1
评论数
最近文章
eject