基于springboot+vue的儿科保健计划免疫系统
基于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>() {@Overridepublic <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() {@Overridepublic 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转化为StingString s = new ObjectMapper().writeValueAsString(ok);out.write(s);out.flush();out.close();}})//登失败回调.failureHandler(myAuthenticationFailureHandler)//相关的接口直接返回.permitAll().and().logout()//注销登录// .logoutSuccessUrl("").logoutSuccessHandler(new LogoutSuccessHandler() {@Overridepublic 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() {@Overridepublic 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();}});}
用户首页模块
@Beanpublic 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);//设置自动启动,默认为truefactory.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进行开发。替换掉原来的框架。以后系统如果再进行二次开发,将更加的容易,配置起来也更便捷。在进行了以上的优化后,我觉得该系统的应用性将大大提升。
九、源码获取:
链接点击直达:下载链接
相关文章:
基于springboot+vue的儿科保健计划免疫系统
基于springbootvue的儿科保健计划免疫系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背…...
1.两数之和
难度简单给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序…...
字符串匹配 - 模式预处理:KMP 算法(Knuth-Morris-Pratt)
Knuth-Morris-Pratt算法(简称KMP)是最常用的字符串匹配算法之一。算法简介如下算法解释主要来源于这里,但是通常很难阅读完全,我推荐你直接进入下一节 图例解释部分。我们来观察一下朴素的字符串匹配算法的操作过程。如下图&#…...
工程师手册:电源设计中的电容选用规则
摘要 电源往往是我们在电路设计过程中最容易忽略的环节。作为一款优秀的设计,电源设计应当是很重要的,它很大程度影响了整个系统的性能和成本。电源设计中的电容使用,往往又是电源设计中最容易被忽略的地方。一、电源设计中电容的工作原理 在…...
【安全开发】专栏文章汇总
安全开发–1–TCP和UDP网络编程 安全开发–2–嗅探邮箱协议口令 安全开发–3–Python实现ARP缓存投毒 安全开发–4–SSH通信工具开发 安全开发–5–编写简单的netcat工具 安全开发–6–一个简单的TCP代理工具开发 安全开发–7–SSH隧道工具开发 安全开发–8–Python实现流量数据…...
视频监控流程图4
<html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"/> <link rel"stylesheet" type"text/css" href"visio.css"/> <title> 视频监控流程图 </title> <…...
「JVM 编译优化」Java 语法糖(泛型、自动装箱/拆箱、条件编译)
「JVM 编译优化」Java 语法糖(泛型、自动装箱/拆箱、条件编译) 语法糖可以看做事前端编译期的一些小把戏;虽不会提供实质性的功能改进,但它们或能提高效率,或能提升语法的严谨性,或能减少编码出错的机会&a…...
Linux下的进程控制
目录 退出码 终止进程 进程等待 进程程序替换 自己实现简易shell命令行 内建命令 退出码 在编写代码时main函数内部我们通常都使用return 0;结尾,以此标识正常退出。这里的return 0就是所谓的退出码,Linux下也是一样: 看这个小程序&…...
QT 文件监视系统QFileSystemWatcher监视目录的改变directoryChanged和监视文件的改变fileChanged
QT 文件监视系统QFileSystemWatcher监视目录的改变相关操作说明mainwindow.hmainwindow.cpp调试结果相关操作说明 添加头文件 Header: #include qmake: QT core bool QFileSystemWatcher::addPath(const QString &path)如果路径存在,则会向文件系统监视器添…...
Typescript基础知识(类型断言、类型别名、字符串字面量类型、枚举、交叉类型)
系列文章目录 引入一:Typescript基础引入(基础类型、元组、枚举) 引入二:Typescript面向对象引入(接口、类、多态、重写、抽象类、访问修饰符) 第一章:Typescript基础知识(Typescri…...
Windows系统扩充C盘空间系列方法总结
目录前言方法一 使用自带的Windows的DiskPart扩充C盘1. 打开cmd2.三步命令方法二:使用Windows系统内置磁盘管理扩展C盘方法三. 使用专业磁盘分区工具总结前言 本教程是总结Windows系统进行C盘(系统盘)扩充空间的系列方法,一般来讲…...
华为OD机试 - 跳格子(Python)
跳格子 题目 地上共有N个格子,你需要跳完地上所有的格子, 但是格子间是有强依赖关系的,跳完前一个格子后, 后续的格子才会被开启,格子间的依赖关系由多组steps数组给出, steps[0]表示前一个格子,steps[1]表示steps[0]可以开启的格子: 比如[0,1]表示从跳完第0个格子以后…...
Java配置文件的值注入
1.平常使用直接在变量头上加上Value就可以把配置文件的值注入进来 Value(“${environment.active}”) private String environment; 2.但是变量使用static修饰时,就不能注入进来了 Value(“${environment.active}”) private static String environment; 这是因…...
SAP 订单BOM与销售BOM的区别
订单BOM与销售BOM的区别 訂單BOM: 是實際生產時用的BOM, 在標準BOM和銷售BOM基礎上增減物料的BOM 銷售BOM: 是為特定客戶設定的BOM, 在主檔數據層次上的BOM, 在生產時是帶到訂單BOM中去的. 標準BOM: 是公司為標準生產的BOM, 在主檔數據層次上的BOM, 在生產時是帶到訂單BOM中去的…...
支付宝支付详细流程
1、二维码的生成二维码生成坐标 <!-- zxing生成二维码 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><dependency><groupId>co…...
TCP 的演化史-fast retransmit/recovery
工作原因要对一个 newreno 实现增加 sack 支持。尝试写了 3 天 C,同时一遍又一遍梳理 sack 标准演进。这些东西我早就了解,但涉及落地写实现,就得不断抠细节,试图写一个完备的实现。 这事有更简单的方法。根本没必要完全实现 RFC…...
CSS基础选择器,你认识多少?
前言在上一文初识CSS中,我们了解到了其格式:选择器{ }在初步尝试使用时,我们笼统的直接输入了p { }以选择p标签来对其操作,而这一章节里,我们再进一步探索有关基础选择器的相关内容,理解选择器的作用。选择…...
ChatGPT入门案例|商务智能对话客服(三)
本篇介绍智能客服的基本功能架构和基本概念,并利用对话流技术构建商务智能应用。 01、商务智能客服功能结构 互联网的发展已经深入到社会的各个方面,智能化发展已经成为社会发展的大趋势。在大数据和互联网时代,企业和组织愈加重视客户沟通…...
Matlab 最小二乘法拟合平面(SVD)
文章目录 一、简介1.1最小二乘法拟合平面1.2 SVD角度二、实现代码三、实现效果参考资料一、简介 1.1最小二乘法拟合平面 之前我们使用过最为经典的方式对平面进行了最小二乘拟合(点云最小二乘法拟合平面),其推导过程如下所示: 仔细观察一下可以发现...
AtCoder Regular Contest 126 D题题解
思路 首先我们看看假设选中 mmm 个数后的答案。 我们首先现将 mmm 个数移动到一起,在将他们重新排序。 我们知道,mmm 个数移在一起时,当位于中间的那个数不动时交换次数最少,于是可以列出式子(cic_ici 是点 iii 的…...
Android R WiFi热点流程浅析
Android R WiFi热点流程浅析 Android上的WiFi SoftAp功能是用户常用的功能之一,它能让我们分享手机的网络给其他设备使用。 那Android系统是如何实现SoftAp的呢,这里在FWK层面做一个简要的流程分析,供自己记录和大家参考。 以Android R版本为…...
【C++进阶】二、多态详解(总)
目录 一、多态的概念 二、多态的定义及实现 2.1 多态的构成条件 2.2 虚函数 2.3 虚函数的重写 2.4 虚函数重写的两个例外 2.4.1 协变 2.4.2 析构函数的重写 2.5 C11 override 和 final 2.5.1 final 2.5.2 override 2.6 重载、覆盖(重写)、隐藏(重定义)的对比 三、…...
node-sass@4.14.1 包含风险, 如何升级依赖至 dart-sass
文章目录需求我上网都查到了哪些信息在 github 看到了 node-sass 依赖的最新版本的列表:关于方案2的失败不同版本的 nodejs 和 node-sass依赖的**适配关系**从何得知替代方案——dart-sass如何安装 dart sass?需求 在做一个基于Node、React的前端项目&a…...
DataWhale 大数据处理技术组队学习task2
三、Hadoop分布式文件系统 1. 产生背景 数据量越来越大,一台独立的计算机已经无法存储所有的数据---->将大规模的数据存储到成百上千的计算机中------为了解决数据管理以及维护极其繁琐与低效------>分布式文件系统 分布式文件系统是管理网络中跨多台计算机…...
一文读懂select、poll、epoll的用法
select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,…...
《C陷阱与缺陷》----词法“陷阱”
导言: 由于一个程序错误可以从不同层面采用不同方式进行考察,而根据程序错误与考察程序的方式之间的相关性,可以将程序错误进行划分为各种陷阱与缺陷: ①.词法“陷阱” ②.语法“陷阱” ③.语义“陷阱” ④.连接问题 ⑤.库函数问…...
千锋教育+计算机四级网络-计算机网络学习-04
UDP概述 UDP协议 面向无连接的用户数据报协议,在传输数据前不需要先建立连接;目地主机的运输层收到UDP报文后,不需要给出任何确认 UDP特点 相比TCP速度稍快些简单的请求/应答应用程序可以使用UDP对于海量数据传输不应该使用UDP广播和多播应用…...
蓝桥杯算法训练合集十四 1.P08052.P07053.同余方程4.P08015.ascii应用
目录 1.P0805 2.P0705 3.同余方程 4.P0801 5.ascii应用 1.P0805 问题描述 当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数&…...
判断字符串中的字符的类型isdecimal();isalpha();isdigit();isalnum()
【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串中的字符的类型 isdecimal();isalpha();isdigit();isalnum() [太阳]选择题 对于代码中isdecimal()和isalnum()输出的结果是? s "ABc123&…...
VSCode远程调试Linux代码,python解释器配置
安装插件并配置 安装后找到插件图标,点击 点击SSH上的 号 在弹出框中输入命令:ssh usernameip -p port username: 远程服务器的用户名 ip: 远程ip port:端口号,没有可以不用 输入完毕后点击enter 选择ssh配置文件保存…...
b2b网站推广技巧/深圳百度快速排名提升
备注:查询时按ctrlf,方便快速查找。小型汽车(蓝牌)川A77HE2 川A9Z05P 川AH39B7 川AJ20N2 川AU7X72 川AV228N川HF3109 川JU9108 川YN4946 鄂A07ZY2 鄂A16KL8 鄂A23B47鄂A23BA7 鄂A6Q120 鄂A71NS2 鄂A71NW9 鄂A83P99 鄂AC1J17鄂AHP189 鄂AR65M1 鄂AV3A97 鄂…...
网站上做旅游卖家要学什么/引流软件有哪些
很久之前就看过attention的相关知识,只是没有动手实践,所以很多小细节没有考虑到. (1)sequence-to-sequence model中,在解码的第一步S0_00是如何计算的就晕了好一阵,下面的图给出了…...
做企业网站好的/seo推广有哪些公司
有时我们需要在html元素的title中换行显示信息。以下几种方法均可以实现: 直接在titile属性中使用换行,如下所示: 1 <a href"asd"title"asdsad2 asdsad3 asd">asdsadsad</a>在title属性中使用AscII码&…...
网站官网建设企业/全网推广代理
2019独角兽企业重金招聘Python工程师标准>>> 浏览器禁止js跨域取数据,可能在两个方面防止,一是ajax取数据的时候发现不是同源,阻止获取数据;另外一种是ajax获取了数据,但是浏览器禁止这些数据在当前域下显示…...
彩票网站做一级代理犯法吗/网络推广公司名字
挂载 NFS 远程目录备份 Oracle 数据库(第13天) ->返回总目录<- 前面讲了如何在 Oracle 本地定时备份数据库,但是这种方式用的人比较少,因为如果本地磁盘坏了就会导致数据库和备份同时丢失,无法找回数据,风险也比较大。 针对这种情况,比较常用的方式是通过存储挂…...
网站跳转代码 html/百度收录提交入口网址是什么
在前面几篇文章我们已经对FreeRTOS任务API和任务调度原理进行了相对深入的分析 这篇文章主要针对任务与任务之间的交互,信息传递相关的API组件进行分析目录一、任务通知基本介绍1、FreeRTOS 任务通知函数2、CMSIS封装后任务通知函数2.1 osSignalSet2.2 osSignalWait…...