基于Springboot+Vue+Sercurity实现的大学生健康管理平台
1.项目介绍
大学生健康档案管理系统,通过电子健康档案管理系统这个平台,可以实现人员健康情况的信息化、网络化、系统化、规范化管理,从繁杂的数据查询和统计中解脱出来,更好的掌握人员健康状况。系统的主要功能包括:人员档案管理、体检管理与疾病信息管理。
本系统前台主要使用Vue作为开发语言,后台使用mysql作为数据库管理系统,开发环境是Idea,开发出的一个基于Web技术的C/S结构的电子健康档案管理系统。
本系统最大的特点是使用操作简单、友好的提示信息。本系统将实现以下基本功能:
-
系统具有简洁大方的页面,使用简便,友好的错误操作提示
-
管理员用户具有人员档案管理、健康体检管理、疾病信息管理、系统管理功能
-
具有较强的安全性,避免用户的恶意操作
1.1 设计背景
紧张的工作节奏、教学和科研的压力、个人不良的工作生活习惯、以及伴随工作压力而来的家庭关系、人际关系紧张等因素使得高校群体成为慢性病的高发群体。学生入学的定期体检,教职工人入职体检,以及所有学生和教职工的定期体检工作,甚至个人自愿定期进行身体健康检查等都离不开医院的体检。人们对体检工作越来越重视,目前,传统的体检一直延用手工管理的方式,对健康信息的可视化平台需求迫切。
实现对健康信息分析的可视化,根据高危人群的日常行为,建立由此引发的发病概率预测模型,对高危人群做出相应的行为干预。健康管理平台不仅包含对个体健康曲线的可视化,同时包含对某群体健康曲线的可视化及预测,并以此为基础对个体日常行为的干预显示,以此为背景我选择设计健康管理平台。
1.2 设计目的和意义
健康管理既是一个概念,也是一种方法,更是一套完善、周密的服务程序,其目的在于使病人以及健康人更好地拥有健康、恢复健康、促进健康并尽量节约经费开支,有效降低医疗支出。健康管理有如下几大作用:一是可以了解居民的身体年龄,判断疾病指向;二是可以根据日常行为判断发病概率,以此为基础由医生提供降低慢性病发生危险性的行为干预方案;三是可以长期(终生)跟踪高危人群的健康,最大限度减少重大疾病的发生;四是可以节省维护健康的时间和金钱,提高保健效率。
建立面向大学生的健康管理平台的目的,对于个人,是如何利用健康体检系统中的信息为人们的健康保驾护航。而健康信息信息管理系统的管理和利用,不仅需要具备基础医学知识、临床医学知识、流行病学知识、计算机技术、数学统计知识等综合素质的专业人员,同时需要有庞大的保健医学、预防医学、临床医学、康复医学等专业的资深专家团队的支持,才能够为个人提供一系列的健康管理服务。
当今世界,信息管理数字化非计算机莫属,只有利用计算机技术,使用我国各个高校统一标准的健康体检系统表格,开发高校健康体检系统的系统软件,设置大学生健康体检系统的计算机编号,制作大学生的健康体检档案,并详细记录其本次体检程中所发现的健康问题和处理情况等,实现用户的健康体检系统信息在学校范围内的网络信息交换和共享,利用计算机技术,对用户的健康体检系统实现连续的动态管理。健康信息管理系统以计算机为工具,通过对用户体检所得的数据进行信息管理,把管理人员从繁琐的数据计算处理中解脱出来,为更好的帮组用户身体健康监督检查,从而全面提高质量。具体通过本系统可以对用户的基本健康状况进行各种必要的统计和分析。
本项目将针对高校群体研发多模态的健康数据采集系统,对历年体检数据、就诊数据、膳食结构、生活习惯等健康相关信息建立统一管理系统,并在此基础上采用数据挖掘方法对诸如心血管疾病、高血压、糖尿病等慢性病进行有效建模与评估,对高校群体内广泛存在的亚健康状态进行综合客观评价和风险预测,最终实现针对高校群体慢性病患者及其高危人群的动态跟踪健康管理与干预。
1.3 国内外研究现状
健康管理的概念最早见于美国,早在1929年美国洛杉矶水利局就成立了最早的健康维护组织。早在20世纪70年代的美国,由于健康保险的发展以及医疗服务模式的改变,要求医生能更好地指导病人进行疾病预防以及更加节省医疗费用。健康服务组织通过对人群的健康状况进行评价和疾病的风险评估,科学预测疾病的危险因素,制定具体的、有针对性的预防和保健措施。通过健康管理美国的医疗费比以前节省了大约10%,同时避免了疾病的发生,提高了生活质量。资料显示,通过健康管理计划,在1978-1983年,美国人的胆固醇水平下降了2%;高血压水平下降了4%;冠心病发病率下降了16%。美国密执安大学健康管理研究中心主任第·艾鼎敦博士(Dee.W.Edington)曾经提出美国20多年的研究得出了9:1定律结论,即90%的人通过健康管理后,医疗费用降到了原来的10%;10%的人未做健康管理,医疗费用比原来上升了90%。通过经济学分析发现,在健康管理方面投入1元钱,相当于减少3-6元医疗费用的开销。如果加上由此产生的劳动生产率提高的回报,实际效益达到投入的8倍。
健康管理在中国刚刚起步,是一个朝阳的产业。目前在中国大陆地区仅有少数专业的健康管理机构,大部分为医院及体检中心的附属部门。健康管理的从业人数没有准确的数据,估计全国在10万人以上,也就是说我国享受科学、专业的健康管理服务的人数只占人口总数的万分之二,这一比例与美国70%居民能够在健康管理公司或企业接受完善的服务相去甚远。而且目前健康管理仍然主要依赖于简单的单次体检或就诊数据由医生提供一些生活习惯的建议和意见,并没有把个人的历史病历以及日常行为对个人慢性病的影响考虑进去。此外,目前的健康管理也主要是针对已患病的患者,还未做到“早筛选、早预防、早发现、早诊断”的动态追踪的健康管理模式。
1.4 软件架构
-
springboot
-
mysql
-
mybatis
-
jpa
-
swagger-ui
-
lombok
2.系统需求分析
2.1 系统目标
健康管理平台的总目标是:在计算机网络,数据库和先进的开发平台上,利用现有的软件,配置一定的硬件,开发一个具有开放体系结构的、易扩充的、易维护的、具有良好人机交互界面的大学生健康管理平台。
具体的要求如下:
-
大学生可以方便的使用五大基本功能
-
独立于具体的数据库平台。对于与数据库交互的部分充分考虑兼容性
-
容易在原先基础上进行二次开发
-
中间基础平台的无型性。尽量采用开放的标准技术,达到跨平台运行的效果
为了达到以上的开发目的,健康管理平台应遵循一定的设计和开发与原则:
-
模块接口定义清晰
-
基础类库和接口设计合理,尽量建立叮扩展的接口和抽象类
-
数据库操作使用标准SQL语句,如果一定要使用有差别的SQL语句,则尽量集中在一起,以减少将来维护和移植的难度
-
采用开放的标准和工具等
2.2 系统的功能要求
2.2.1 前台功能
在前台的功能实现上,可以分为以下几个部分:
-
大学生健康阅读 :每日可以在首页进行健康资料阅读
-
大学生健康日志 :用户可以记录自己健康日记,记录每一天的睡眠,饮酒,吸烟,血压,体重等情况
-
大学生体检管理 :大学生可通过该平台查询每次的体检结果,显示部分项目随时间变化的曲线
-
疾病预测评估 :针对糖尿病和高血压两种疾病,利用数学线性回归的方法,模拟计算出大学生患病概率
2.2.2 后台功能
后台主要有四个功能:
-
管理员用户登录功能 :通过编号登录系统
-
管理员管理大学生功能 :可以增删改查大学生基本信息
-
管理员管理体检结果 :可以增删改查大学生体检记录
-
管理员对体检表,健康文档,体检数据图标展示等进行管理,以及权限管理 :指定不同科室医生进行不同的操作
2.3 系统的性能需求
健康管理平台的特性要求网站系统需要具备以下几个主要特性:
-
多样性 :健康管理平台在设计时必须遵循的一个重要原则,就是以用户为系统设计的中心。网络的发展大大降低了信息咨询的成本,用户面临更多的选择,所以,健康管理平台除了降低成本以外,还必须在外观,功能的多样性上下工夫,才能够得到用户的认可。具体来说,应用系统应能实现用户特定的需求,操作界面友好、方便,功能设置符合用户的习惯和要求
-
易维护 :管理员能够简单方便地管理系统,定义新的应用,并对系统进行日常维护;随着健康管理平台信息的变更或增加、数据规模的增大,系统升级、维护应易于操作;各子系统、功能模块的设计应具有良好的灵活性,保证在健康管理平台系统建设过程中后期系统功能的实现不影响前期已投入使用的系统功能
-
安全性 :系统应充分考虑信息、设备、运行和管理的安全性,建立完善的多层次的安全保障体系,保证用户的个人信息等资料的数据安全
-
可扩展 :健康管理平台的用户从事着各种行业,他们的需求各不相同,系统在设计时应充分考虑到用户需求不断变化的需要,降低系统在扩展新的业务功能时的复杂度[5]
2.4 系统的数据要求
2.4.1 数据的性质
数据录入和处理的准确性和实时性
数据的输入是否准确是数据处理的前提,错误的输入会导致系统输出的不正确和不可用,从而使系统的工作失去意义。数据的输入来源是用户的手工输入。手工输入要通过系统界面上的安排系统具有容错性,并且对用户操作进行实时的跟踪和错误提示。
在系统中,数据的输入往往是大量的,因此系统要有一定的处理能力,以保证迅速的处理数据。
数据的一致性与完整性
由于网站的数据是共享的,所以如何保证这些数据的一致性,是网站必须解决的问题。要解决这一问题,要有一定的人员维护数据的一致性,在数据录入处控制数据的去向,并且要求对数据库的数据完整性进行严格的约束。
对于输入的数据,要为其定义完整性规则,如果不能符合完整性约束,网站应该拒绝该数据。
数据的共享与独立性
整个健康管理平台的数据是共享的。然而,从网站开发的角度上看,共享会给设计和调试带来困难。因此,应该提供灵活的配置,使各个分系统能够独立运行,而通过人工干预的手段进行系统数据的交换。这样,也能提供系统的强壮性。
2.4.2 数据字典
健康管理平台主要涉及到真实姓名数据字典,如表2.1所示:
真实姓名数据字典
系统信息表
报告信息表
权限表
权限资源表
资源表
健康阅读表
检查报告表
2.4.3 实体联系图
3.项目实现
3.1 项目说明
项目是采用SpringBoot + Mybatis + Shiro 的搭建的单体后台服务。同时通过引入通用mapper减少代码量,已达到重点关注业务的开发。
xml
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper-starter-version}</version>
<exclusions>
<exclusion>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
</exclusion>
</exclusions>
</dependency>
3.1.1 实体
在创建实体时,首先定义了一个
BaseEntity
的类,所有的实体均集成该类,同时该类需要加上
@MappedSuperclass
注解。
BaseEntity
里面包含了所有实体的公共字段,如:id、createTime、updateTime。这样做是为了减少代码的冗余。
实体上配置了
@Table
注解,以及实体字段配置了
@Column
注解是为了搭配jpa的自动建表,已达到添加字段时,重新运行项目,数据库表字段也会自动添加。
但是存在缺点: 更改字段类型或删除字段,数据库表不能自动修改或删除字段,需要手动去变更。
3.1.2 Dao层
再创建相关的dao层接口时,需要接口继承自定义的
BaseDao
接口,该接口集成了通用mapper相关的接口和注解,便于我们自定义一些通用接口。
3.1.3 Service层
所有的service接口需要继承自定义的
BaseService
接口,该接口定义了一些常用到的接口,例如增、删、改、查等等。
java
public interface BaseService<T> {
List<T> selectAll();
T selectByKey(Serializable key);
int insert(T entity);
int deleteByKey(Serializable key);
int deletes(List<String> keys);
int delete(T entity);
int update(T entity);
List<T> selectByExample(Example example);
List<T> select(Condition condition);
PageInfo<T> selectPage(Condition condition);
}
同时创建接口实现类时需要继承自定义的
BaseServiceImpl
类,该类实现了
BaseService
接口的所有方法,这样可以达到不用书写这些接口,就可在需要的时候调用,如果需要自定义某个方法时,只需要实通过
@Override
重写某个方法即可。
java
@Slf4j
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true,rollbackFor = Exception.class)
public abstract class BaseServiceImpl<T, M extends BaseDao<T>> implements BaseService<T> {
private Class<?> clazz = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
@Autowired
protected M entityDao;
@Override
public List<T> selectAll() {
return entityDao.selectAll();
}
@Override
public T selectByKey(Serializable key) {
log.info("执行筛选==>参数为【"+key+"】");
return entityDao.selectByPrimaryKey(key);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int insert(T entity) {
log.info("执行插入==>参数为【"+entity+"】");
return entityDao.insertSelective(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteByKey(Serializable key) {
log.info("执行删除==>参数为【"+key+"】");
return entityDao.deleteByPrimaryKey(key);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deletes(List<String> keys) {
log.info("执行批量删除==>参数为【"+keys+"】");
String keyName = null;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Id.class)) {
keyName = field.getName();
break;
}
}
Example example = new Example(clazz);
example.createCriteria().andIn(keyName,keys);
return entityDao.deleteByExample(example);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int delete(T entity) {
log.info("执行删除==>参数为【"+entity+"】");
if (entity != null){
return entityDao.delete(entity);
}
return 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int update(T entity) {
log.info("执行修改==>参数为【"+entity+"】");
return entityDao.updateByPrimaryKeySelective(entity);
}
@Override
public List<T> selectByExample(Example example) {
return entityDao.selectByExample(example);
}
@Override
public List<T> select(Condition condition) {
log.info("执行条件查询===>参数为【"+JSONObject.toJSONString(condition) +"】");
Map<String, EntityColumn> propertyMap = EntityHelper.getEntityTable(clazz).getPropertyMap();
Example example = new Example(clazz);
List<Clause> clauses = condition.getClauses();
if (!CollectionUtils.isEmpty(clauses)) {
Example.Criteria criteria = example.createCriteria();
clauses.forEach(clause -> {
if(!StringUtils.isEmpty(clause.getColumn())){
if("isNull".equalsIgnoreCase(clause.getOperation())){
criteria.andIsNull(clause.getColumn());
}
if("isNotNull".equalsIgnoreCase(clause.getOperation())) {
criteria.andIsNotNull(clause.getColumn());
}
else{
if (!StringUtils.isEmpty(clause.getValue())) {
if("between".equalsIgnoreCase(clause.getOperation())){
ArrayList<?> list= (ArrayList<?>) clause.getValue();
criteria.andBetween(clause.getColumn(),list.get(0),list.get(1));
}
if ("like".equalsIgnoreCase(clause.getOperation())) {
criteria.andLike(clause.getColumn(), "%" + clause.getValue() + "%");
}
if("=".equalsIgnoreCase(clause.getOperation())) {
criteria.andCondition(propertyMap.get(clause.getColumn()).getColumn() + clause.getOperation(), clause.getValue());
}
}
}
}
});
}
Map<String, Object> sortMap = condition.getSortMap();
if (sortMap.size()>0) {
StringBuffer sb = new StringBuffer();
sortMap.forEach((k, v) -> {
if (!StringUtils.isEmpty(k) && !StringUtils.isEmpty(v)) {
sb.append(propertyMap.get(k).getColumn());
sb.append(" ");
sb.append(v);
sb.append(",");
}
});
if (sb.toString().endsWith(",")) {
sb.deleteCharAt(sb.length() - 1);
}
example.setOrderByClause(sb.toString());
}
return selectByExample(example);
}
@Override
public PageInfo<T> selectPage(Condition condition) {
PageHelper.startPage(condition.getPageNum(), condition.getPageSize());
List<T> list = select(condition);
return new PageInfo<>(list);
}
}
3.1.4 Web层
在web层,项目定义了一个
BaseController
的抽象类,里面实体了基本的增删改查的接口定义。再我们创建某个模块的Controller时只需要继承该类就
可达到不用在创建的类下面定义接口,也会自动拥有相关接口,如果需要对某个接口方法做定制时,只需要重新某个方法就可以了。
java
@Slf4j
public abstract class BaseController<S extends BaseService<T>,T,ID extends Serializable> {
@Autowired
protected S service;
@ApiOperation(value = "基础接口: 新增操作")
@PostMapping(value = "add")
public ResponseEntity<T> save(@RequestBody T entity){
try {
if ( service.insert(entity)<1){
throw new MyException(ExceptionEnums.ADD_ERROR);
}
}catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.ADD_ERROR);
}
return ResponseEntity.ok(entity);
}
@ApiOperation(value = "基础接口: 返回指定ID的数据")
@GetMapping(value = "get/{id}")
public ResponseEntity<T> get(@PathVariable("id")ID id){
T t = null;
try {
t = service.selectByKey(id);
}catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.GET_ITEM);
}
return ResponseEntity.ok(t);
}
@ApiOperation(value = "基础接口: 返回所有数据")
@GetMapping(value = "all")
public ResponseEntity<List<T>> all(){
List<T> list;
try {
list = service.selectAll();
}catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.GET_LIST_ERROR);
}
return ResponseEntity.ok(list);
}
@ApiOperation(value = "基础接口: 分页返回数据")
@PostMapping(value = "page")
public ResponseEntity<PageInfo<T>> page(@RequestBody Condition condition){
PageInfo<T> page ;
try {
page = service.selectPage(condition);
}catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.GET_LIST_ERROR);
}
return ResponseEntity.ok(page);
}
@ApiOperation(value = "基础接口: 修改数据")
@PostMapping(value = "update")
public ResponseEntity<T> update(@RequestBody T entity){
try {
if (service.update(entity)<1){
throw new MyException(ExceptionEnums.UPDATE_ERROR);
}
}catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.UPDATE_ERROR);
}
return ResponseEntity.ok(entity);
}
@ApiOperation(value = "基础接口: 删除指定ID的数据")
@GetMapping(value = "delete/{id}")
public ResponseEntity<String> delete(@PathVariable("id")ID id){
try {
if ( service.deleteByKey(id)<1){
throw new MyException(ExceptionEnums.DELETE_ERROR);
}
} catch (Exception e){
log.error(e.getMessage());
throw new MyException(ExceptionEnums.DELETE_ERROR);
}
return ResponseEntity.ok("删除成功");
}
}
3.2 权限相关
权限主要采用apache shiro,需要引入相关依赖
xml
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
在使用shiro时,需要创建一个realm进行进行权限的授权和认证,同时需要创建一个自定义的凭证验证器来校验密码是否一致。配置好这些后需要定义一个shiro的配置类
ShiroConfiguration
来配置shiro的权限过滤工厂bean
ShiroFilterFactoryBean
,在里面引入自定义的
AuthRealm
bean以达到权限的校验。
因为项目采用的是前后端分离,会产生跨域请求等问题,所以需要开放所有来源对该服务的请求,所以需要配置相关过滤器
CorsFilter
。
java
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//是否支持cookie跨域
httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
//指定允许其他域名访问
httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));
//响应头设置
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,client_id, uuid, Authorization,user-agent,X-XSRF-TOKEN");
// 设置过期时间
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
//响应类型
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
// 支持HTTP1.1.
httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
// 支持HTTP 1.0.
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setHeader("Allow","GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
if ("OPTIONS".equals(httpServletRequest.getMethod())) {
httpServletResponse.setStatus(204);
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() { }
}
使用shiro权限验证时,第一次请求为option方式,所以要配置shiro过滤掉option方式,不对此方式做权限拦截。故配置
ShiroFilter
java
@Slf4j
public class ShiroFiter extends FormAuthenticationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
boolean allowed = super.isAccessAllowed(request, response, mappedValue);
if (!allowed) {
// 判断请求是否是options请求
String method = WebUtils.toHttp(request).getMethod();
if (StringUtils.equalsIgnoreCase("OPTIONS", method)) {
return true;
}
}
return allowed;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
return super.onAccessDenied(request, response);
}
}
3.3 其他
项目中定义了全局异常捕获,再项目中需要抛出异常时只需要抛出自定义的异常
MyException
,就可对该异常进行捕获,当用户请求某个接口如果出现异常时,后台服务就会返回自定义的错误代码,不会出现乱码的情况,以便于前端对返回结果做统一处理或错误拦截。同时我们也可预先自定义需要抛出的错误,在前段可对错误code进行区别,采用不同的样式提示。
java
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum ExceptionEnums {
/**
* 错误返回信息
*/
NO_CHECK_INFO(400,"暂无健康档案表,无法进行数据分析"),
CHOOSE_FILE(400,"文件未上传"),
IS_NOT_LOGIN(400,"用户未登录"),
UPLOAD_FAIL(400,"上传失败"),
RESOURCE_FOUNT_FAIL(400,"获取菜单权限失败!"),
NOT_AUTHORIZED(403,"您暂无权限访问该资源!"),
ACCOUNT_IS_EXIT(400,"用户名已存在"),
PASSWORD_WRONG(400,"密码错误"),
ACCOUNT_IS_NOT_EXIT(400,"用户名不存在"),
UPDATE_ERROR(400,"更新失败"),
ADD_ERROR(400,"新增失败"),
DELETE_ERROR(400,"删除失败"),
GET_LIST_ERROR(400,"获取列表失败"),
GET_ITEM(400,"获取对象失败"),
NO_WEIGHT_HEIGHT(400,"当前档案未完善身高体重信息")
;
/**
* 代码值
*/
private int code;
/**
* 消息
*/
private String msg;
}
3.4 跨域配置
java
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",buildConfig());
return new CorsFilter(source);
}
3.5 安装教程
-
mysql本地创建数据库,导入sql文件
-
修改项目yml数据库配置文件为自己的配置
-
运行项目
-
在运行前端项目
4.项目展示
登录页
4.1 医生用户
首页
健康建议
健康阅读
添加文章
健康档案管理
查看档案
修改密码
4.2 普通用户
主页
个人信息
查看个人档案
健康阅读
4.3 管理员用户
主页
角色管理
新增角色
用户管理
权限管理
5.系统测试
5.1 编写测试用例
登陆测试用例
字段名称 | 描述 |
---|---|
标识符 | UC001 |
测试项 | 用户登录功能测试 |
测试环境要求 | 1.用户test/pass为有效登陆用户,用户test1为无效登录用户; 2.浏览器的cookie为被禁用 |
输入标准 | 1.用户输入正确的用户名和密码,单击登陆按钮; 2.输入错误的用户名密码,单击登陆按钮; 3.不输入用户名密码,单击登陆; 4.输入正确的用户名不输入密码,单击登陆 |
输出标准 | 1.数据库中存在的用户可以正确登陆 2.显示错误提示界面 3.提示“请输入用户名” 4.提示“请输入密码” |
注册测试用例
字段名称 | 描述 |
---|---|
标识符 | UC002 |
测试项 | 用户注册功能测试 |
测试环境要求 | 用户未注册过 |
输入标准 | 1.用户输入真实名字大于四个或小于两个 2.用户输入手机号不是11位 3.用户输入邮箱不含@ 4.用户必填项输入为空 |
输出标准 | 1.系统提示输入正确的名字 2.系统提示输入正确的手机号 3.系统提示输入正确的邮箱格式 ” 4.系统提示完成所有必要输入 |
5.2 单元测试
在单元测试的时候,主要测试的是前后台各功能模块的功能是否都正常运行,是否和预期的结果相同,页面间的跳转和页面数据显示是否正常,实现的方式是单步调试,调试工具是用PostMan,辅助工具使用IE的脚本调试。在PostMan中设置断点,跟踪语句,逐句或者逐过程的调试,对出现的问题进行记录,并在完成所有测试后,对BUG进行了修复。
5.3 系统和集成测试
系统测试是通过将健康管理的前后系统进行整合,整体的测试平台的性能,测试前后台是否有数据不匹配,或者数据冲突等问题。集成测试是将整个平台放在服务器上,通过远程的访问、使用,测试系统平台是否能正常运行,通过使用VS2005提供的压力测试工具,对平台进行压力测试,以测试在用户使用高峰期时,平台的承受能力。
集成压力测试方法:
-
创建测试项目
-
添加Web测试
-
运行健康管理平台,此时web测试工具将对网站的相应操作记录,记录充足后停止记录,并生成相应代码
-
添加负载测试
-
在向导中设置需要测试环境,运行测试
6.结论
本文从健康管理平台所需要实现的功能模块开始分析,决定使用Java开发该网站。并利用JDK,Idea,Navicat等软件来搭建开发环境,利用Java技术的SpringBoot+Mybatis等开源框架设计三层结构的中业务逻辑层和数据服务层,健康管理平台以SpringBoot 框架为核心,向下整合MybatisPlus进行持久层访问;向上整合按清晰的MVC 模式控制,并且采用spring.security做安全和权限管理。这样可以更快开发松散耦合的健康管理平台。通过这次毕业设计学会利用java构建Web 网站,在毕业设计中接触过不少开源框架。开源框架的强大让我觉得还有很多技术需要去学习,这也让我明白,要不断地学习新知识才会利于自己各方面的发展。
参考文献
- 基于Spring Boot的校园轻博客系统的设计与实现(华中科技大学·邓笑)
- 基于Android的健康管理平台的设计与实现(天津科技大学·李承阔)
- 学生综合信息管理平台的设计与实现(吉林大学·刘铁刚)
- 基于微服务的政务机构服务系统的研究与设计(北京邮电大学·周博凯)
- 宁夏医科大学学生信息管理系统的设计与实现(西安科技大学·闫静)
- 基于Java EE平台的个人健康信息管理系统设计与实现(南京邮电大学·贾顺贺)
- 基于J2EE平台MVC模式的个人健康管理系统的设计与实现(南昌大学·单文英)
- 宁夏医科大学学生信息管理系统的设计与实现(西安科技大学·闫静)
- 基于SSH框架的健康生活平台的构建(复旦大学·范翔宇)
- 基于J2EE的学生信息管理系统(电子科技大学·钟海琴)
- 基于J2EE平台MVC模式的个人健康管理系统的设计与实现(南昌大学·单文英)
- 基于.NET的学生事务管理系统的设计与实现(电子科技大学·郑华)
- 基于Java EE平台的个人健康信息管理系统设计与实现(南京邮电大学·贾顺贺)
- 在线学习过程管理系统软件设计与实现(北京邮电大学·王嘉康)
- 基于Java EE平台的个人健康信息管理系统设计与实现(南京邮电大学·贾顺贺)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码客栈网 ,原文地址:https://bishedaima.com/yuanma/35511.html