基于springboot+vue的儿科保健计划免疫系统
✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌
🍅文末获取项目下载方式🍅
一、项目背景介绍:
随着科学技术的发展,尤其是计算机技术、网络技术、多媒体技术、传感技术、控制技术和智能技术的发展,人类进入了信息时代。信息时代的标志是Internet国际互联网的建立。Internet国际互联网将世界各地紧密地联系在一起。于是一个数字化得社区应运而生。
当前,西方发达国家的网络化、智能化、自动化达到很高的水平,已经或正在改变人们的生产方式和生活方式,许多国家的计划免疫部门早已实现无纸化办公,我们国家有些城市已经实现免疫信息管理的网上办公,但是并没有完全普遍,目前随着儿童计划免疫改革的不断深入,如何有效地增强儿童免疫接种信息管理水平,充分提高信息管理的效率已成为计划免疫管理工作的重点之一。
二、项目技术简介:
- JAVA:Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
- Vue:Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,帮助开发者高效地开发用户界面。
Vue是一个独立的社区驱动的项目,它是由尤雨溪在2014年作为其个人项目创建, 是一个成熟的、经历了无数实战考验的框架,它是目前生产环境中使用最广泛的JavaScript框架之一,可以轻松处理大多数web应用的场景,并且几乎不需要手动优化,并且Vue完全有能力处理大规模的应用。 - Element-UI:Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
- Spring:Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于J2EE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
- SpringBoot:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
- Mybatis-Plus:MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为 简化开发、提高效率而生。
- Spring-Mvc:Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框。
- Redis:redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 - Html:HTML的全称为超文本标记语言,是一种标记语言。它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整体。HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字,图形、动画、声音、表格、链接等。
超文本是一种组织信息的方式,它通过超级链接方法将文本中的文字、图表与其他信息媒体相关联。这些相互关联的信息媒体可能在同一文本中,也可能是其他文件,或是地理位置相距遥远的某台计算机上的文件。这种组织信息方式将分布在不同位置的信息资源用随机方式进行连接,为人们查找,检索信息提供方便。 - shiro:Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
三、系统功能模块介绍:
四、数据库设计:
1:QRTZ_BLOB_TRIGGERS(QRTZ_BLOB_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
BLOB_DATA | blob | NULL |
2:QRTZ_CALENDARS(QRTZ_CALENDARS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
CALENDAR_NAME | varchar(200) | NULL | |
CALENDAR | blob | NULL |
3:QRTZ_CRON_TRIGGERS(QRTZ_CRON_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
CRON_EXPRESSION | varchar(120) | NULL | |
TIME_ZONE_ID | varchar(80) | NULL |
4:QRTZ_FIRED_TRIGGERS(QRTZ_FIRED_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
ENTRY_ID | varchar(95) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
INSTANCE_NAME | varchar(200) | NULL | |
FIRED_TIME | bigint(13) | NULL | |
SCHED_TIME | bigint(13) | NULL | |
PRIORITY | int(11) | NULL | |
STATE | varchar(16) | NULL | |
JOB_NAME | varchar(200) | NULL | |
JOB_GROUP | varchar(200) | NULL | |
IS_NONCONCURRENT | varchar(1) | NULL | |
REQUESTS_RECOVERY | varchar(1) | NULL |
5:QRTZ_JOB_DETAILS(QRTZ_JOB_DETAILS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
JOB_NAME | varchar(200) | NULL | |
JOB_GROUP | varchar(200) | NULL | |
DESCRIPTION | varchar(250) | NULL | |
JOB_CLASS_NAME | varchar(250) | NULL | |
IS_DURABLE | varchar(1) | NULL | |
IS_NONCONCURRENT | varchar(1) | NULL | |
IS_UPDATE_DATA | varchar(1) | NULL | |
REQUESTS_RECOVERY | varchar(1) | NULL | |
JOB_DATA | blob | NULL |
6:QRTZ_LOCKS(QRTZ_LOCKS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
LOCK_NAME | varchar(40) | NULL |
7:QRTZ_PAUSED_TRIGGER_GRPS(QRTZ_PAUSED_TRIGGER_GRPS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL |
8:QRTZ_SCHEDULER_STATE(QRTZ_SCHEDULER_STATE)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
INSTANCE_NAME | varchar(200) | NULL | |
LAST_CHECKIN_TIME | bigint(13) | NULL | |
CHECKIN_INTERVAL | bigint(13) | NULL |
9:QRTZ_SIMPLE_TRIGGERS(QRTZ_SIMPLE_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
REPEAT_COUNT | bigint(7) | NULL | |
REPEAT_INTERVAL | bigint(12) | NULL | |
TIMES_TRIGGERED | bigint(10) | NULL |
10:QRTZ_SIMPROP_TRIGGERS(QRTZ_SIMPROP_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
STR_PROP_1 | varchar(512) | NULL | |
STR_PROP_2 | varchar(512) | NULL | |
STR_PROP_3 | varchar(512) | NULL | |
INT_PROP_1 | int(11) | NULL | |
INT_PROP_2 | int(11) | NULL | |
LONG_PROP_1 | bigint(20) | NULL | |
LONG_PROP_2 | bigint(20) | NULL | |
DEC_PROP_1 | VARCHAR(255) | NULL |
11:QRTZ_TRIGGERS(QRTZ_TRIGGERS)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
SCHED_NAME | varchar(120) | NULL | |
TRIGGER_NAME | varchar(200) | NULL | |
TRIGGER_GROUP | varchar(200) | NULL | |
JOB_NAME | varchar(200) | NULL | |
JOB_GROUP | varchar(200) | NULL | |
DESCRIPTION | varchar(250) | NULL | |
NEXT_FIRE_TIME | bigint(13) | NULL | |
PREV_FIRE_TIME | bigint(13) | NULL | |
PRIORITY | int(11) | NULL | |
TRIGGER_STATE | varchar(16) | NULL | |
TRIGGER_TYPE | varchar(8) | NULL | |
START_TIME | bigint(13) | NULL | |
END_TIME | bigint(13) | NULL | |
CALENDAR_NAME | varchar(200) | NULL | |
MISFIRE_INSTR | smallint(2) | NULL | |
JOB_DATA | blob | NULL |
12:appointment(appointment)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | ID |
user_name | varchar(50) | NULL | 用户名 |
name | varchar(50) | NULL | 真实姓名 |
gender | varchar(50) | NULL | 性别 |
appoint_date | date | NULL | 接种日期 |
time | varchar(50) | NULL | 日期 |
appoint_site | varchar(50) | NULL | 服务点 |
which_pin | varchar(50) | NULL | 针数 |
vaccine | varchar(50) | NULL | 疫苗 |
status | varchar(20) | NULL |
13:banners(banners)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
banner_id | int(11) | NULL | |
content | varchar(255) | NULL | 知识内容 |
image_url | varchar(500) | NULL | |
sort | int(10) | NULL | 排序 |
is_show | int(10) | NULL | 是否展示 |
title | varchar(50) | NULL |
14:history(history)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | |
name | varchar(255) | NULL | |
phone | varchar(255) | NULL | |
gender | varchar(255) | NULL | |
age | int(11) | NULL | |
first_pin | int(255) | NULL | |
second_pin | int(255) | NULL | |
first_date | datetime(0) | NULL | |
second_date | datetime(0) | NULL | |
user_name | varchar(255) | NULL |
15:inoculation_site(inoculation_site)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | |
name | varchar(255) | NULL | |
province | varchar(255) | NULL | |
city | varchar(255) | NULL | |
address | varchar(255) | NULL |
16:inspection(inspection)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
registration_id | int(11) | NULL | ID |
username | varchar(10) | NULL | 姓名 |
card | varchar(20) | NULL | 身份证 |
address | varchar(50) | NULL | 住址 |
sex | varchar(10) | NULL | 性别 |
phone | varchar(20) | NULL | 手机号 |
check_cate | varchar(20) | NULL | 预检状态 |
create_time | datetime(0) | NULL | 预检日期 |
handle_status | varchar(10) | NULL | 处理状态 |
17:options(options)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
option_id | int(11) | NULL | |
content | varchar(255) | NULL | |
opt_type | varchar(10) | NULL | A |
18:pi_sign(pi_sign)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
sign_id | int(11) | NULL | ID |
user_id | varchar(10) | NULL | 用户id |
username | varchar(10) | NULL | 签到人 |
nickname | varchar(10) | NULL | 职业 |
create_time | datetime(0) | NULL | 创建时间 |
19:questions(questions)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
question_id | int(10) | NULL | |
que_type | tinyint(1) | NULL | 问题类型:0:单选;1:多选; |
content | varchar(255) | NULL | 问题内容 |
answer | varchar(255) | NULL | 答案 |
score | int(10) | NULL | 分数 |
from_data | varchar(20) | NULL | 题库 |
20:schedule_job(schedule_job)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
job_id | bigint(20) | NULL | 任务id |
bean_name | varchar(200) | NULL | springbean名称 |
params | varchar(2000) | NULL | 参数 |
cron_expression | varchar(100) | NULL | cron表达式 |
status | tinyint(4) | NULL | 任务状态0:正常1:暂停 |
remark | varchar(255) | NULL | 备注 |
create_time | datetime(0) | NULL | 创建时间 |
21:schedule_job_log(schedule_job_log)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
log_id | bigint(20) | NULL | 任务日志id |
job_id | bigint(20) | NULL | 任务id |
bean_name | varchar(200) | NULL | springbean名称 |
params | varchar(2000) | NULL | 参数 |
status | tinyint(4) | NULL | 任务状态0:成功1:失败 |
error | varchar(2000) | NULL | 失败信息 |
times | int(11) | NULL | 耗时(单位:毫秒) |
create_time | datetime(0) | NULL | 创建时间 |
22:stay(stay)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | ID |
user_name | varchar(255) | NULL | 姓名 |
phone | varchar(255) | NULL | 电话 |
reason | varchar(255) | NULL | 留观原因 |
create_time | datetime(0) | NULL | 留观时间 |
23:sys_captcha(sys_captcha)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
uuid | char(36) | NULL | uuid |
code | varchar(6) | NULL | 验证码 |
expire_time | datetime(0) | NULL | 过期时间 |
24:sys_config(sys_config)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | bigint(20) | NULL | |
param_key | varchar(50) | NULL | key |
param_value | varchar(2000) | NULL | value |
status | tinyint(4) | NULL | 状态0:隐藏1:显示 |
remark | varchar(500) | NULL | 备注 |
25:sys_log(sys_log)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | bigint(20) | NULL | |
username | varchar(50) | NULL | 用户名 |
operation | varchar(50) | NULL | 用户操作 |
method | varchar(200) | NULL | 请求方法 |
params | varchar(5000) | NULL | 请求参数 |
time | bigint(20) | NULL | 执行时长(毫秒) |
ip | varchar(64) | NULL | IP地址 |
create_date | datetime(0) | NULL | 创建时间 |
26:sys_menu(sys_menu)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
menu_id | bigint(20) | NULL | |
parent_id | bigint(20) | NULL | 父菜单ID,一级菜单为0 |
name | varchar(50) | NULL | 菜单名称 |
url | varchar(200) | NULL | 菜单URL |
perms | varchar(500) | NULL | 授权(多个用逗号分隔,如:user:list |
27:sys_oss(sys_oss)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | bigint(20) | NULL | |
url | varchar(200) | NULL | URL地址 |
create_date | datetime(0) | NULL | 创建时间 |
28:sys_role(sys_role)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
role_id | bigint(20) | NULL | |
role_name | varchar(100) | NULL | 角色名称 |
remark | varchar(100) | NULL | 备注 |
create_user_id | bigint(20) | NULL | 创建者ID |
create_time | datetime(0) | NULL | 创建时间 |
29:sys_role_menu(sys_role_menu)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | bigint(20) | NULL | |
role_id | bigint(20) | NULL | 角色ID |
menu_id | bigint(20) | NULL | 菜单ID |
30:sys_user(sys_user)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
user_id | bigint(20) | NULL | |
username | varchar(50) | NULL | 用户名 |
password | varchar(100) | NULL | 密码 |
salt | varchar(20) | NULL | 盐 |
varchar(100) | NULL | 邮箱 | |
mobile | varchar(100) | NULL | 手机号 |
status | tinyint(4) | NULL | 状态0:禁用1:正常 |
create_user_id | bigint(20) | NULL | 创建者ID |
create_time | datetime(0) | NULL | 创建时间 |
gender | varchar(10) | NULL | |
age | int(11) | NULL | |
card | varchar(255) | NULL | |
address | varchar(255) | NULL |
31:sys_user_role(sys_user_role)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | bigint(20) | NULL | |
user_id | bigint(20) | NULL | 用户ID |
role_id | bigint(20) | NULL | 角色ID |
32:sys_user_token(sys_user_token)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
user_id | bigint(20) | NULL | |
token | varchar(100) | NULL | token |
expire_time | datetime(0) | NULL | 过期时间 |
update_time | datetime(0) | NULL | 更新时间 |
33:tb_user(tb_user)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
user_id | bigint(20) | NULL | |
username | varchar(50) | NULL | 用户名 |
mobile | varchar(20) | NULL | 手机号 |
password | varchar(64) | NULL | 密码 |
create_time | datetime(0) | NULL | 创建时间 |
34:user_exam(user_exam)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
exam_id | int(11) | NULL | |
nick_name | varchar(100) | NULL | |
gender | varchar(10) | NULL | |
avatar_url | varchar(255) | NULL | |
score | int(10) | NULL |
35:user_info(user_info)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | |
user_name | varchar(255) | NULL | |
real_name | varchar(255) | NULL | |
gender | varchar(255) | NULL | |
age | int(11) | NULL | |
card | varchar(255) | NULL | |
phone | varchar(255) | NULL | |
address | varchar(255) | NULL |
36:user_score(user_score)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
score_id | int(10) | NULL | |
dan_score | int(10) | NULL | |
duo_score | int(10) | NULL | |
write_score | int(10) | NULL | |
total_score | int(10) | NULL |
37:vaccines_info(vaccines_info)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
id | int(11) | NULL | |
inoculation_site | varchar(255) | NULL | |
name | varchar(255) | NULL | |
type | varchar(255) | NULL | |
production | varchar(255) | NULL | |
batch_number | varchar(50) | NULL | |
describ | varchar(255) | NULL |
38:wx_user(wx_user)
字段名 | 类型 | 默认值 | 列注释 |
---|---|---|---|
user_id | int(10) | NULL | |
username | varchar(50) | NULL | 用户名 |
password | varchar(50) | NULL | 密码 |
phone | varchar(50) | NULL | 电话 |
user_avatar | varchar(100) | NULL | 头像 |
create_time | datetime(0) | NULL | 创建时间 |
nickname | varchar(50) | NULL | 昵称 |
sex | varchar(10) | NULL | 性别 |
五、功能模块:
-
系统登入模块:该模块主要是用户进行登录的模块,在该页面用户输入自己的账号和密码,验证码是用随机数来进行生成的,是完全随机的,输入验证码要与旁边验证码要一致。然后点击登录,登录成功后就进入主页面了。
这小节主要是介绍登录功能的设计,然后是讲述登录功能是如何实现的。当你在地址栏输入该系统的网络地址,进入到本页面。然后输入自己的账号和密码,输入的时候要考虑几个注意事项。账号和密码都不能为空,为空会提示账号或密码不能为空。当输入完用户名密码后,选择自己的角色,每个角色的页面都是不一样的,功能也是有所不同。最后就是输入验证码,验证码是用ArithmeticCaptcha这个类来进行生成的,这个类是一个验证码生成的类,使用该类可以生成一个算术的验证码,调用里面的setLen方法可以定义几位数的算法来进行运算,最后调用toBase64方法把生成的验证码转化为一个。最后使用一个map集合进行封装,返回给前端验证。在前台我们要经过一个二位数的算数运算得出结果,并填写在输入框。如果我们不进行填写,直接提交的话,会提示验证码未输入。如果验证码输入错误,也会提示验证码错误。
在访问该系统登录时,后台会进行拦截,这里讲一下后台是怎么配置的。在进行登录的时候,会发起一个doLogin请求,后台会进行一个拦截。首先请求必须是post请求,不然直接返回异常信息。然后就是验证码的校验,如果验证码为空,会提示验证码不存在。当你每次提交验证码都会通过session进行缓存,如果再次请求验证码,就会提示验证码过期。你输入的验证码必须和里面算出来的结果一致,不然就会提示验证码不匹配。如果中间出现任何异常,都会配catch抓获AuthenticationException类的一个异常。只有验证码通过以后才会与后台数据库进行交互,与数据库中的账户进行一一匹配,匹配成功,就会进入到主页面。但是在在此期间使用了Spring shiro来进行登录的鉴权。首先定义一个SecurityConfig配置类来继承WebSecurityConfigurerAdapter主类。我们需要往里面注入BCryptPasswordEncoder依赖。然后我们需要重写里面的configure方法,然后在里面配置放行的请求路径,比如"/login",还有我们所需要的静态资源。然后最主要的是protect修饰的configure类,我们需要传一个HttpSecurity作为参数。这里主要是各种执行器来进行操作,包括使用withObjectPostProcessor对后台传过来的参数和url做一个处理,使用successHandler或者failureHandler对登录成功和失败的一个回调,使用authenticationEntryPoint做一个鉴权等等。具体的数据交互在AuthenticationManagerBuilder里面,我们需要自定义一个service然后继承UserDetailsService,然后我们就可以进行一系列数据库操作,将我们自定义的service类注入到AuthenticationManagerBuilder中,然后SecurityConfig就可以为我们到数据库进行查询然后对角色进行登录鉴权。 -
用户首页模块:儿科保健系统首页界面实现了对数据得到统计的展示功能
-
用户签到模块:用户可以在用户签到模块对自己进行签到
-
疫苗预约模块:用户可以在疫苗预约模块对自己需要的疫苗进行预约
-
接种管理模块:接种管理模块在这个模块管理员可以对用户接种疫苗信息进行管理
六、代码示例:
系统登入模块
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
//.anyRequest().authenticated()
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> O postProcess(O object) {
object.setAccessDecisionManager(customUrlDecisionManager);
object.setSecurityMetadataSource(customFilterInvocationSecurityMetadataSource);
return object;
}
})
.and().formLogin().usernameParameter("username").passwordParameter("password").loginProcessingUrl("/doLogin")
.loginPage("/login")
//登录成功回调
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
Hr hr = (Hr) authentication.getPrincipal();
//密码不回传
hr.setPassword(null);
RespBean ok = RespBean.ok("登录成功!", hr);
//将hr转化为Sting
String s = new ObjectMapper().writeValueAsString(ok);
out.write(s);
out.flush();
out.close();
}
})
//登失败回调
.failureHandler(myAuthenticationFailureHandler)
//相关的接口直接返回
.permitAll()
.and()
.logout()
//注销登录
// .logoutSuccessUrl("")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException, ServletException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
out.write(new ObjectMapper().writeValueAsString(RespBean.ok("注销成功!")));
out.flush();
out.close();
}
})
.permitAll()
.and()
.csrf().disable().exceptionHandling()
//没有认证时,在这里处理结果,不要重定向
.authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest req, HttpServletResponse resp, AuthenticationException authException) throws IOException, ServletException {
resp.setContentType("application/json;charset=utf-8");
resp.setStatus(401);
PrintWriter out = resp.getWriter();
RespBean respBean = RespBean.error("访问失败!");
if (authException instanceof InsufficientAuthenticationException) {
respBean.setMsg("请求失败,请联系管理员!");
}
out.write(new ObjectMapper().writeValueAsString(respBean));
out.flush();
out.close();
}
});}
用户首页模块
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
//quartz参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
//线程池配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
//JobStore配置
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
//集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
//PostgreSQL数据库,需要打开此注释
//prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
factory.setQuartzProperties(prop);
factory.setSchedulerName("RenrenScheduler");
//延时启动
factory.setStartupDelay(30);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
//可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
//设置自动启动,默认为true
factory.setAutoStartup(true);
return factory;
}
}
用户签到模块
@PostMapping("/blurredQuery")
public Result<List> blurredQuery(@RequestBody @NotNull Map<String,String> map) {
Result<List> result = new Result<>();
List<Employee> employeeList = employeeService.getAllEmployee();
List<Employee> list = new ArrayList<>();
if (map.get("name").equals("") && map.get("state").equals("")) {
result.setCode(200);
result.setMsg("查询成功,条件无");
result.setSuccess(true);
result.setData(employeeList);
} else if ((!map.get("name").equals("")) && map.get("state").equals("")) {
// employeeList.forEach((item) -> {
// if (item.getName().equals(map.get("name"))) {
// result.setData(item);
// }
// });
for (Employee e : employeeList) {
if (map.get("name").equals(e.getName())) {
list.add(e);
result.setCode(200);
result.setMsg("查询成功");
result.setSuccess(true);
}
}
result.setData(list);
} else if (map.get("name").equals("") && !map.get("state").equals("")) {
for (Employee e : employeeList) {
if (map.get("state").equals(e.getState())) {
list.add(e);
}
}
result.setCode(200);
result.setMsg("查询成功");
result.setSuccess(true);
result.setData(list);
} else {
for (Employee e : employeeList) {
if (map.get("state").equals(e.getState()) && map.get("name").equals(e.getName())) {
list.add(e);
}
}
result.setCode(200);
result.setMsg("查询成功");
result.setSuccess(true);
result.setData(list);
}
return result;
}
疫苗预约模块
@ApiOperation("/新增预约")
@PostMapping("/addOneAppointment")
public R addOneAppointment(@RequestBody Appointment appointment) {
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
appointment.setUserName(username);
appointment.setStatus("已预约");
appointmentService.addOne(appointment);
return R.ok().put("info", "预约成功");
}
@ApiOperation("/取消预约")
@GetMapping("/cancelAppointment")
public Result<Appointment> cancelAppointment(@RequestParam String userName) {
Result<Appointment> result = new Result<>();
result.setMsg("取消预约失败");
result.setCode(400);
if (userName.equals("")) {
result.setMsg("参数为空");
result.setCode(400);
result.setSuccess(false);
result.setData(null);
} else {
if (appointmentService.findByUserName(userName) == null) {
result.setCode(200);
result.setSuccess(true);
result.setMsg("您还未预约");
} else {
appointmentService.cancelOne(userName);
result.setCode(200);
result.setMsg("取消预约成功");
result.setSuccess(true);
}
}
return result;
}
@ApiOperation("/根据日期查询预约")
@GetMapping("/findByDate")
public Result<List> findByDate(@RequestParam Date date) {
Result<List> result = new Result<>();
result.setMsg("查询预约失败");
result.setCode(400);
if (date == null) {
result.setMsg("参数为空");
result.setCode(400);
result.setSuccess(false);
} else {
List<Appointment> appointmentList = appointmentService.findByDate(date);
if (appointmentList == null) {
result.setSuccess(false);
result.setCode(400);
result.setMsg("该日期没有预约");
} else {
result.setMsg("查询成功");
result.setCode(200);
result.setSuccess(true);
result.setData(appointmentList);
}
}
return result;
}
接种管理模块
@ApiOperation("/根据省或市查询具体接种点")
@PostMapping("/findBySiteInfo")
public Result<List> findBySiteInfo(@RequestBody InoculationSiteInfo siteInfo){
Result<List> result = new Result<>();
if (siteInfo == null){
result.setMsg("参数为空");
result.setCode(400);
result.setSuccess(false);
} else {
if ( siteInfo.getCity().equals("") ) {
List<InoculationSite> inoculationSiteList =
inoculationSiteService.findByProvince(siteInfo.getProvince());
result.setData(inoculationSiteList);
result.setCode(200);
result.setSuccess(true);
result.setMsg("成功");
} else {
List<InoculationSite> inoculationSiteList =
inoculationSiteService.findByProvinceAndCity(siteInfo);
result.setCode(200);
result.setSuccess(true);
result.setMsg("成功");
result.setData(inoculationSiteList);
}
}
return result;
}
七、论文参考:
八、项目总结:
网络时代的即将到来,给人类带来的冲击是前所未有的,同时它也为信息管理提供了实现飞跃的机遇。信息的管理要面向现代化、面向世界、面向未来,首先要面向网络。只有与网络有机结合,才能跟上时代的发展,有了网络通过不同的权限设置可以对不同的登陆者进行相应的操作,我的这个系统就本着这种方向去实现。
由于时间仓促的问题,系统存在着些许的不足之处,系统所用的框架比较老旧,以后的维护可能存在一些潜在的问题,没有用现在比较前沿的框架,程序员就是应该不断创新,不断学习。只有这样才能更好提升自我。再就是后台异常的处理,比如你登录该系统时路径不正确或错误,应该是要跳转到404页面或者是其他异常页面,我没有对其进行处理,主要是前面页面功能花了太多时间,后面没有太多的时间进行优化。
在将来,系统在以下几个方面进行优化。首先对于系统整个进行优化处理,像页面的美化,页面是用户进行交互的界面,好的页面对用户来说,更加的友好,操作也更舒服。还有异常页面的拦截,用户输入了一个错误的地址,应该被后台拦截,然后跳转到一个自己设计好的页面。这样用户才能知道自己究竟哪里出问题了。最后就是框架,我将采用SpringCloud+Vue进行开发。替换掉原来的框架。以后系统如果再进行二次开发,将更加的容易,配置起来也更便捷。在进行了以上的优化后,我觉得该系统的应用性将大大提升。
九、源码获取:
链接点击直达:下载链接