一,环境介绍
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
前端开发技术:微信小程序+Vue+ElementUI
后台开发技术: springboot+mybatis-plus
二,项目简介
2.1 基本介绍
信息化技术在目前的中国,己得到普遍应用,涉及到民生的各个方面和角度,教育上的信息化应用、医疗上的信息改革、交通上的信息化普及等等,业己显示中国在向科技强国的方向前进。
中国经济水平的提升也让中国人民的日子富裕起来了,富裕生活的开始也让老百姓的对自身的健康日益重视起来了,中国的全面发展也带动了全民医疗资源的普及,看病就医也越来越方便。如何利用现代化技术手段,基于移动互联网技术,让老百姓更加方便快捷的进行在线预约就诊,这就是本系统要着重解决的问题。
经过调查和走访研发的这套在线就诊预约管理系统,采用微信小程序开发实现,基于MySQL数据库进行数据存储,前端使用微信小程序开发实现,后端基于Springboot框架,以及Nodejs开发实现,前端页面展示采用Vue+ElementUI实现。系统前端用户主要实现查看资讯信息、挂号大厅实现在线预约挂号、查看自己的预约、修改个人资料等;医生用户可以通过微信小程序端查看预约患者、填写诊断情况、管理预约信息等。后台主要实现用户管理、内容管理、活动和预约管理、统计预约用户数等功能。这套系统的上线对于人们就医就诊提供了很大方便,节约很多时间。
2.2 需求分析
基于微信小程序开发实现这套就诊预约管理系统,经过调研分析,得出需要两类用户角色,一类是系统的前端用户,一类是后端管理员用户。前端用户又分为患者用户和医生用户,患者通过微信小程序登陆后,主要的需求是通过此平台获得最新的资讯信息推送和在线预约挂号;医生用户登陆小程序端后主要就是通过此平台查看预约信息并填写就诊说明,同时发布预约时间信息等 。后台管理员用户主要实现相关数据的的管理功能,一是实现新闻动态的管理操作,二是实现预约信息的管理,三是实现注册用户的信息管理功能,四是进行在线信息的查看统计等功能。
2.3 功能设计
根据调查走访后进行的需求分析,得出基于微信小程序的在线就诊预约管理系统的各用户角色的主要功能模块图,如下图所示。
后台管理员登陆后台管理系统可以实现的主要功能模块有:用户管理、公告管理、轮播图管理、资讯分类管理、资讯信息管理、挂号信息管理、信息统计报表等功能。
图2-1 后台功能结构图
前端患者用户注册后可以登陆微信小程序,主要实现查看系统公告、查看相关资讯信息、查看挂号大厅里的就诊医生信息并进行在线挂号,对资讯文章进行点赞收藏,对医生进行评论,并可以在个人中心查看个人收藏的信息,维护个人信息,并可以维护自己的预约挂号信息。
图2-2 小程序端患者用户功能结构图
前端医生用户登陆微信小程序,主要实现查看系统公告、查看相关资讯信息、查看挂号大厅里的就诊医生信息,对资讯文章进行点赞收藏,查看预约了自己就诊时段的预约信息并进行管理,并可以在个人中心查看个人收藏的信息,维护个人信息,并可以发布自己的预约挂号信息。
图2-3 小程序端医生用户功能结构图
2.4 数据库设计
数据库表的详细设计主要基于实体模型的分析,在主要业务字段的基础上添加一些数据存储的必要字段比较主键信息等。下面展示一下就诊预约系统中涉及到的数据库物理表结构。
article_type:资读文章分类信息表,主要存储资讯文章分类信息。
表3-1资讯分类信息表(article_type)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
type_id |
smallint(5) unsigned |
否 |
<auto_increment> |
分类ID:[0,10000] |
|
display |
smallint(4) unsigned |
否 |
100 |
显示顺序:[0,1000]决定分类显示的先后顺序 |
|
name |
varchar(16) |
否 |
分类名称:[2,16] |
||
father_id |
smallint(5) unsigned |
否 |
0 |
上级分类ID:[0,32767] |
|
description |
varchar(255) |
是 |
<空> |
描述:[0,255]描述该分类的作用 |
|
icon |
text |
是 |
分类图标: |
||
url |
varchar(255) |
是 |
<空> |
外链地址:[0,255]如果该分类是跳转到其他网站的情况下,就在该URL上设置 |
|
create_time |
timestamp |
否 |
<INSERT-TimeStamp> |
创建时间: |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间: |
article:资讯文章信息表,主在存储发布的一些新闻资讯,可以在前端分类展示。
表3-2 资讯信息表(article)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
article_id |
mediumint(8) unsigned |
否 |
<auto_increment> |
文章id:[0,8388607] |
|
title |
varchar(125) |
否 |
标题:[0,125]用于文章和html的title标签中 |
||
type |
varchar(64) |
否 |
0 |
文章分类:[0,1000]用来搜索指定类型的文章 |
|
hits |
int(10) unsigned |
否 |
0 |
点击数:[0,1000000000]访问这篇文章的人次 |
|
praise_len |
int(11) |
否 |
0 |
点赞数 |
|
create_time |
timestamp |
否 |
<INSERT-TimeStamp> |
创建时间: |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间: |
|
source |
varchar(255) |
是 |
<空> |
来源:[0,255]文章的出处 |
|
url |
varchar(255) |
是 |
<空> |
来源地址:[0,255]用于跳转到发布该文章的网站 |
|
tag |
varchar(255) |
是 |
<空> |
标签:[0,255]用于标注文章所属相关内容,多个标签用空格隔开 |
|
content |
longtext |
是 |
正文:文章的主体内容 |
||
img |
varchar(255) |
是 |
<空> |
封面图 |
|
description |
text |
是 |
文章描述 |
registration_hall:挂号大厅信息表,主要存储发布的医生挂号信息。
表3-3 挂号大厅信息表(registration_hall)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
registration_hall_id |
int(11) |
否 |
<auto_increment> |
挂号大厅ID |
|
department_number |
varchar(64) |
否 |
科室编号 |
||
department_name |
varchar(64) |
是 |
<空> |
科室名称 |
|
visiting_physician |
int(11) |
是 |
0 |
出诊医生 |
|
visit_time |
varchar(64) |
是 |
<空> |
出诊时间 |
|
number_of_source |
int(11) |
是 |
0 |
号源数量 |
|
roster_status |
varchar(64) |
是 |
<空> |
排班状态 |
|
doctor_photos |
varchar(255) |
是 |
<空> |
医生照片 |
|
doctor_profile |
longtext |
是 |
医生简介 |
||
hits |
int(11) |
否 |
0 |
点击数 |
|
praise_len |
int(11) |
否 |
0 |
点赞数 |
|
recommend |
int(11) |
否 |
0 |
智能推荐 |
|
create_time |
datetime |
否 |
<INSERT-TimeStamp> |
创建时间 |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间 |
registration_information:前端用户预约信息表,主要存储前端用户的预约信息。
表3-4 预约信息表(registration_information)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
registration_information_id |
int(11) |
否 |
<auto_increment> |
挂号信息ID |
|
reservation_user |
int(11) |
是 |
0 |
预约用户 |
|
time_of_appointment |
varchar(64) |
是 |
<空> |
预约时间 |
|
contact_number |
varchar(64) |
是 |
<空> |
联系电话 |
|
department_number |
varchar(64) |
是 |
<空> |
科室编号 |
|
department_name |
varchar(64) |
是 |
<空> |
科室名称 |
|
visiting_physician |
int(11) |
是 |
0 |
出诊医生 |
|
visit_time |
varchar(64) |
是 |
<空> |
出诊时间 |
|
number_of_appointments |
varchar(64) |
是 |
<空> |
预约人数 |
|
visit_status |
varchar(64) |
是 |
<空> |
就诊状态 |
|
user_comments |
text |
是 |
用户备注 |
||
doctor_advice |
text |
是 |
医生建议 |
||
recommend |
int(11) |
否 |
0 |
智能推荐 |
|
create_time |
datetime |
否 |
<INSERT-TimeStamp> |
创建时间 |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间 |
ordinary_users:前端注册用户信息表,主要存储前端注册的用户信息。
表3-5 前端注册用户信息表(ordinary_users)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
ordinary_users_id |
int(11) |
否 |
<auto_increment> |
普通用户ID |
|
user_name |
varchar(64) |
否 |
用户姓名 |
||
user_gender |
varchar(64) |
是 |
<空> |
用户性别 |
|
user_age |
varchar(64) |
是 |
<空> |
用户年龄 |
|
id |
varchar(255) |
是 |
<空> |
身份证 |
|
date_of_birth |
varchar(64) |
是 |
<空> |
出生年月 |
|
examine_state |
varchar(16) |
否 |
已通过 |
审核状态 |
|
recommend |
int(11) |
否 |
0 |
智能推荐 |
|
user_id |
int(11) |
否 |
0 |
用户ID |
|
create_time |
datetime |
否 |
<INSERT-TimeStamp> |
创建时间 |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间 |
notice:系统公告信息表,主要存储系统发布的公告信息。
表3-6 系统公告信息表(notice)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
notice_id |
mediumint(8) unsigned |
否 |
<auto_increment> |
公告id: |
|
title |
varchar(125) |
否 |
标题: |
||
content |
longtext |
是 |
正文: |
||
create_time |
timestamp |
否 |
<INSERT-TimeStamp> |
创建时间: |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间: |
doctor_user:医生信息表,主要存储系统中涉及到的医生信息。
表3-7 医生信息表(doctor_user)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
doctor_user_id |
int(11) |
否 |
<auto_increment> |
医生用户ID |
|
doctor_job_number |
varchar(64) |
否 |
医生工号 |
||
name_of_doctor |
varchar(64) |
是 |
<空> |
医生姓名 |
|
doctor_gender |
varchar(64) |
是 |
<空> |
医生性别 |
|
doctor_age |
varchar(64) |
是 |
<空> |
医生年龄 |
|
id |
varchar(64) |
是 |
<空> |
身份证 |
|
date_of_birth |
varchar(64) |
是 |
<空> |
出生年月 |
|
doctor_certificate |
varchar(255) |
是 |
<空> |
医生证件 |
|
examine_state |
varchar(16) |
否 |
已通过 |
审核状态 |
|
recommend |
int(11) |
否 |
0 |
智能推荐 |
|
user_id |
int(11) |
否 |
0 |
用户ID |
|
create_time |
datetime |
否 |
<INSERT-TimeStamp> |
创建时间 |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间 |
comment:评论信息表,主要存储用户对医生的评论信息。
表3-8 评论信息表(comment)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
comment_id |
int(11) unsigned |
否 |
<auto_increment> |
评论ID: |
|
user_id |
int(11) unsigned |
否 |
0 |
评论人ID: |
|
reply_to_id |
int(11) unsigned |
否 |
0 |
回复评论ID:空为0 |
|
content |
longtext |
是 |
内容: |
||
nickname |
varchar(255) |
是 |
<空> |
昵称: |
|
avatar |
varchar(255) |
是 |
<空> |
头像地址:[0,255] |
|
create_time |
timestamp |
否 |
<INSERT-TimeStamp> |
创建时间: |
|
update_time |
timestamp |
否 |
<INSERT-TimeStamp> |
更新时间: |
|
source_table |
varchar(255) |
是 |
<空> |
来源表: |
|
source_field |
varchar(255) |
是 |
<空> |
来源字段: |
|
source_id |
int(10) unsigned |
否 |
0 |
来源ID: |
User:后台管理用户信息表,主要存储后台登陆用户信息。
表3-9 后台用户信息表(user)
名称 |
类型 |
空 |
默认值 |
其他 |
备注 |
user_id |
mediumint(8) unsigned |
否 |
<auto_increment> |
用户ID:[0,8388607]用户获取其他与用户相关的数据 |
|
state |
smallint(1) unsigned |
否 |
1 |
账户状态:[0,10](1可用|2异常|3已冻结|4已注销) |
|
user_group |
varchar(32) |
是 |
<空> |
所在用户组:[0,32767]决定用户身份和权限 |
|
login_time |
timestamp |
否 |
<INSERT-TimeStamp> |
上次登录时间: |
|
phone |
varchar(11) |
是 |
<空> |
手机号码:[0,11]用户的手机号码,用于找回密码时或登录时 |
|
phone_state |
smallint(1) unsigned |
否 |
0 |
手机认证:[0,1](0未认证|1审核中|2已认证) |
|
username |
varchar(16) |
否 |
用户名:[0,16]用户登录时所用的账户名称 |
||
nickname |
varchar(16) |
是 |
昵称:[0,16] |
||
password |
varchar(64) |
否 |
密码:[0,32]用户登录所需的密码,由6-16位数字或英文组成 |
||
varchar(64) |
是 |
邮箱:[0,64]用户的邮箱,用于找回密码时或登录时 |
|||
email_state |
smallint(1) unsigned |
否 |
0 |
邮箱认证:[0,1](0未认证|1审核中|2已认证) |
|
avatar |
varchar(255) |
是 |
<空> |
头像地址:[0,255] |
|
create_time |
timestamp |
否 |
<INSERT-TimeStamp> |
创建时间: |
三,系统展示
用户登录
系统首页
在线预约
后台登录
用户管理
轮播图管理
挂号信息管理
挂号统计
内容管理
四,核心代码展示
package com.project.demo.controller.base; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.project.demo.service.base.BaseService; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import javax.persistence.Query; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; /** */ @Slf4j public class BaseController<E, S extends BaseService<E>> { @Setter protected S service; @PostMapping("/add") @Transactional public Map<String, Object> add(HttpServletRequest request) throws IOException { service.insert(service.readBody(request.getReader())); return success(1); } @Transactional public Map<String, Object> addMap(Map<String,Object> map){ service.insert(map); return success(1); } @PostMapping("/set") @Transactional public Map<String, Object> set(HttpServletRequest request) throws IOException { service.update(service.readQuery(request), service.readConfig(request), service.readBody(request.getReader())); return success(1); } @RequestMapping(value = "/del") @Transactional public Map<String, Object> del(HttpServletRequest request) { service.delete(service.readQuery(request), service.readConfig(request)); return success(1); } @RequestMapping("/get_obj") public Map<String, Object> obj(HttpServletRequest request) { Query select = service.select(service.readQuery(request), service.readConfig(request)); List resultList = select.getResultList(); if (resultList.size() > 0) { JSONObject jsonObject = new JSONObject(); jsonObject.put("obj",resultList.get(0)); return success(jsonObject); } else { return success(null); } } @RequestMapping("/get_list") public Map<String, Object> getList(HttpServletRequest request) { Map<String, Object> map = service.selectToPage(service.readQuery(request), service.readConfig(request)); return success(map); } @RequestMapping("/list_group") public Map<String, Object> listGroup(HttpServletRequest request) { Map<String, Object> map = service.selectToList(service.readQuery(request), service.readConfig(request)); return success(map); } @RequestMapping("/bar_group") public Map<String, Object> barGroup(HttpServletRequest request) { Map<String, Object> map = service.selectBarGroup(service.readQuery(request), service.readConfig(request)); return success(map); } @RequestMapping(value = {"/count_group", "/count"}) public Map<String, Object> count(HttpServletRequest request) { Query count = service.count(service.readQuery(request), service.readConfig(request)); return success(count.getResultList()); } @RequestMapping(value = {"/sum_group", "/sum"}) public Map<String, Object> sum(HttpServletRequest request) { Query count = service.sum(service.readQuery(request), service.readConfig(request)); return success(count.getResultList()); } @RequestMapping(value = {"/avg_group", "/avg"}) public Map<String, Object> avg(HttpServletRequest request) { Query count = service.avg(service.readQuery(request), service.readConfig(request)); return success(count.getResultList()); } @PostMapping("/upload") public Map<String, Object> upload(@RequestParam("file") MultipartFile file) { log.info("进入方法"); if (file.isEmpty()) { return error(30000, "没有选择文件"); } try { //判断有没路径,没有则创建 String filePath = System.getProperty("user.dir") + "\\target\\classes\\static\\upload\\"; File targetDir = new File(filePath); if (!targetDir.exists() && !targetDir.isDirectory()) { if (targetDir.mkdirs()) { log.info("创建目录成功"); } else { log.error("创建目录失败"); } } // String path = ResourceUtils.getURL("classpath:").getPath() + "static/upload/"; // String filePath = path.replace('/', '\\').substring(1, path.length()); String fileName = file.getOriginalFilename(); File dest = new File(filePath + fileName); log.info("文件路径:{}", dest.getPath()); log.info("文件名:{}", dest.getName()); file.transferTo(dest); JSONObject jsonObject = new JSONObject(); jsonObject.put("url", "/api/upload/" + fileName); return success(jsonObject); } catch (IOException e) { log.info("上传失败:{}", e.getMessage()); } return error(30000, "上传失败"); } @PostMapping("/import_db") public Map<String, Object> importDb(@RequestParam("file") MultipartFile file) throws IOException { service.importDb(file); return success(1); } @RequestMapping("/export_db") public void exportDb(HttpServletRequest request, HttpServletResponse response) throws IOException { HSSFWorkbook sheets = service.exportDb(service.readQuery(request), service.readConfig(request)); response.setContentType("application/octet-stream"); response.setHeader("Content-disposition", "attachment;filename=employee.xls"); response.flushBuffer(); sheets.write(response.getOutputStream()); sheets.close(); } public Map<String, Object> success(Object o) { Map<String, Object> map = new HashMap<>(); if (o == null) { map.put("result", null); return map; } if (o instanceof List) { if (((List) o).size() == 1) { o = ((List) o).get(0); map.put("result", o); }else { String jsonString = JSONObject.toJSONString(o); JSONArray objects = service.covertArray(JSONObject.parseArray(jsonString)); map.put("result", objects); } } else if (o instanceof Integer || o instanceof String) { map.put("result", o); } else { String jsonString = JSONObject.toJSONString(o); JSONObject jsonObject = JSONObject.parseObject(jsonString); JSONObject j = service.covertObject(jsonObject); map.put("result", j); } return map; } public Map<String, Object> error(Integer code, String message) { Map<String, Object> map = new HashMap<>(); map.put("error", new HashMap<String, Object>(4) {{ put("code", code); put("message", message); }}); return map; } }
五,相关作品展示
基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目
基于Nodejs、Vue等前端技术开发的前端实战项目
基于微信小程序和安卓APP应用开发的相关作品
基于51单片机等嵌入式物联网开发应用
基于各类算法实现的AI智能应用
基于大数据实现的各类数据管理和推荐系统