默认打包方式就是jar包
1.1 项目介绍
传智健康管理系统是一款应用于健康管理机构的业务系...
默认打包方式就是jar包
1.1 项目介绍
传智健康管理系统是一款应用于健康管理机构的业务系统,实现健康管理机构工作内容可视化、会员管理专业化、健康评估数字化、健康干预流程化、知识库集成化,从而提高健康管理师的工作效率,加强与会员间的互动,增强管理者对健康管理机构运营情况的了解。
详见:资料中的传智健康PRD文档.docx
1.2 原型展示
参见资料中的静态原型。
1.3 技术架构
1.4 功能架构
1.5 软件开发流程
软件开发一般会经历如下几个阶段,整个过程是顺序展开,所以通常称为瀑布模型。
2.1 项目结构
本项目采用maven分模块开发方式,即对整个项目拆分为几个maven工程,每个maven工程存放特定的一类代码,具体如下:
各模块职责定位:
health_parent:父工程,打包方式为pom,统一锁定依赖的版本,同时聚合其他子模块便于统一执行maven命令
health_common:通用模块,打包方式为jar,存放项目中使用到的一些工具类、实体类、返回结果和常量类
health_interface:打包方式为jar,存放服务接口
health_service_provider:Dubbo服务模块,打包方式为war,存放服务实现类、Dao接口、Mapper映射文件等,作为服务提供方,需要部署到tomcat运行
health_backend:传智健康管理后台,打包方式为war,作为Dubbo服务消费方,存放Controller、HTML页面、js、css、spring配置文件等,需要部署到tomcat运行
health_mobile:移动端前台,打包方式为war,作为Dubbo服务消费方,存放Controller、HTML页面、js、css、spring配置文件等,需要部署到tomcat运行
2.2 maven项目搭建
通过前面的项目功能架构图可以知道本项目分为传智健康管理后台和传智健康前台(微信端)
2.2.1 health_parent
创建health_parent,父工程,打包方式为pom,用于统一管理依赖版本
pom.xml
2.2.2 health_common
创建health_common,子工程,打包方式为jar,存放通用组件,例如工具类、实体类等
pom.xml
2.2.5 health_interface
创建health_interface,子工程,打包方式为jar,存放服务接口
pom.xml
2.2.6 health_service_provider
创建health_service_provider,子工程,打包方式为war,作为服务单独部署,存放服务类、Dao接口和Mapper映射文件等
pom.xml
log4j.properties
SqlMapConfig.xml
spring-dao.xml
spring-tx.xml
spring-service.xml
web.xml
2.2.7 health_backend
创建health_backend,子工程,打包方式为war,单独部署,存放Controller、页面等
pom.xml
log4j.properties
springmvc.xml
web.xml
3.1 Power Designer介绍
PowerDesigner是Sybase公司的一款软件,使用它可以方便地对系统进行分析设计,他几乎包括了数据库模型设计的全过程。利用PowerDesigner可以制作数据流程图、概念数据模型、物理数据模型、面向对象模型。
在项目设计阶段通常会使用PowerDesigner进行数据库设计。使用PowerDesigner可以更加直观的表现出数据库中表之间的关系,并且可以直接导出相应的建表语句。
3.2 Power Designer使用
3.2.1 创建物理数据模型
操作步骤:
(1)创建数据模型PDM
(2)选择数据库类型
(3)创建表和字段
指定表名
创建字段
设置某个字段属性,在字段上右键
添加外键约束
3.2.2 从PDM导出SQL脚本
可以通过PowerDesigner设计的PDM模型导出为SQL脚本,如下:
3.2.3 逆向工程
上面我们是首先创建PDM模型,然后通过PowerDesigner提供的功能导出SQL脚本。实际上这个过程也可以反过来,也就是我们可以通过SQL脚本逆向生成PDM模型,这称为逆向工程,操作如下:
3.2.4 生成数据库报表文件
通过PowerDesigner提供的功能,可以将PDM模型生成报表文件,具体操作如下:
(1)打开报表向导窗口
(2)指定报表名称和语言
(3)选择报表格式和样式
(4)选择对象类型
(5)执行生成操作
4.1 ElementUI介绍
ElementUI是一套基于VUE2.0的桌面端组件库,ElementUI提供了丰富的组件帮助开发人员快速构建功能强大、风格统一的页面。
官网地址:http://element-cn.eleme.io/#/zh-CN
传智健康项目后台系统就是使用ElementUI来构建页面,在页面上引入 js 和 css 文件即可开始使用,如下:
4.2 常用组件
4.2.1 Container 布局容器
用于布局的容器组件,方便快速搭建页面的基本结构:
:外层容器。当子元素中包含 或 时,全部子元素会垂直上下排列,否则会水平左右排列
:顶栏容器
:侧边栏容器
:主要区域容器
:底栏容器
4.2.2 Dropdown 下拉菜单
将动作或菜单折叠到下拉菜单中。
4.2.3 NavMenu 导航菜单
为网站提供导航功能的菜单。
4.2.4 Table 表格
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
4.2.5 Pagination 分页
当数据量过多时,使用分页分解数据。
4.2.6 Message 消息提示
常用于主动操作后的反馈提示。
4.2.7 Tabs 标签页
分隔内容上有关联但属于不同类别的数据集合。
4.2.8 Form 表单
由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。在 Form 组件中,每一个表单域由一个 Form-Item 组件构成,表单域中可以放置各种类型的表单控件,包括 Input、Select、Checkbox、Radio、Switch、DatePicker、TimePicker。
传智健康管理系统是一款应用于健康管理机构的业务系统,实现健康管理机构工作内容可视化、患者管理专业化、健康评估数字化、健康干预流程化、知识库集成化,从而提高健康管理师的工作效率,加强与患者间的互动,增强管理者对健康管理机构运营情况的了解。
系统分为传智健康后台管理系统和移动端应用两部分。其中后台系统提供给健康管理机构内部人员(包括系统管理员、健康管理师等)使用,微信端应用提供给健康管理机构的用户(体检用户)使用。
本项目功能架构图:
通过上面的功能架构图可以看到,传智健康后台管理系统有会员管理、预约管理、健康评估、健康干预等功能。移动端有会员管理、体检预约、体检报告等功能。后台系统和移动端应用都会通过Dubbo调用服务层发布的服务来完成具体的操作。本项目属于典型的SOA架构形式。
本章节完成的功能开发是预约管理功能,包括检查项管理、检查组管理、体检套餐管理、预约设置等(参见产品原型)。预约管理属于系统的基础功能,主要就是管理一些体检的基础数据。
2.1 导入预约管理模块数据表
操作步骤:
(1)根据资料中提供的itcasthealth.pdm文件导出SQL脚本
[外链图片转存中…(img-zoZELX6M-1653196547507)]
[外链图片转存中…(img-h1GZoIGo-1653196547508)]
(2)创建本项目使用的数据库itcast_health
[外链图片转存中…(img-KektvFlO-1653196547509)]
(3)将PowerDesigner导出的SQL脚本导入itcast_health数据库进行建表
[外链图片转存中…(img-KBtVwhwL-1653196547510)]
2.2 导入预约管理模块实体类
将资料中提供的POJO实体类复制到health_common工程中。
2.3 导入项目所需公共资源
项目开发过程中一般会提供一些公共资源,供多个模块或者系统来使用。
本章节我们导入的公共资源有:
(1)返回消息常量类MessageConstant,放到health_common工程中
(2)返回结果Result和PageResult类,放到health_common工程中
(3)封装查询条件的QueryPageBean类,放到health_common工程中
(4)html、js、css、图片等静态资源,放到health_backend工程中
注意:后续随着项目开发还会陆续导入其他一些公共资源。
3.1 完善页面
检查项管理页面对应的是checkitem.html页面,根据产品设计的原型已经完成了页面基本结构的编写,现在需要完善页面动态效果。
3.1.1 弹出新增窗口
页面中已经提供了新增窗口,只是处于隐藏状态。只需要将控制展示状态的属性dialogFormVisible改为true就可以显示出新增窗口。
新建按钮绑定的方法为handleCreate,所以在handleCreate方法中修改dialogFormVisible属性的值为true即可。同时为了增加用户体验度,需要每次点击新建按钮时清空表单输入项。
3.1.2 输入校验
3.1.3 提交表单数据
点击新增窗口中的确定按钮时,触发handleAdd方法,所以需要在handleAdd方法中进行完善。
3.2 后台代码
3.2.1 Controller
在health_backend工程中创建CheckItemController
3.2.2 服务接口
在health_interface工程中创建CheckItemService接口
3.2.3 服务实现类
在health_service_provider工程中创建CheckItemServiceImpl实现类
3.2.4 Dao接口
在health_service_provider工程中创建CheckItemDao接口,本项目是基于Mybatis的Mapper代理技术实现持久层操作,故只需要提供接口和Mapper映射文件,无须提供实现类
3.2.5 Mapper映射文件
在health_service_provider工程中创建CheckItemDao.xml映射文件,需要和CheckItemDao接口在同一目录下
本项目所有分页功能都是基于ajax的异步请求来完成的,请求参数和后台响应数据格式都使用json数据格式。
请求参数包括页码、每页显示记录数、查询条件。
请求参数的json格式为:{currentPage:1,pageSize:10,queryString:‘‘itcast’’}
后台响应数据包括总记录数、当前页需要展示的数据集合。
响应数据的json格式为:{total:1000,rows:[]}
如下图:
[外链图片转存中…(img-pn0AN3li-1653196547513)]
4.1 完善页面
4.1.1 定义分页相关模型数据
4.1.2 定义分页方法
在页面中提供了findPage方法用于分页查询,为了能够在checkitem.html页面加载后直接可以展示分页数据,可以在VUE提供的钩子函数created中调用findPage方法
4.1.3 完善分页方法执行时机
除了在created钩子函数中调用findPage方法查询分页数据之外,当用户点击查询按钮或者点击分页条中的页码时也需要调用findPage方法重新发起查询请求。
为查询按钮绑定单击事件,调用findPage方法
为分页条组件绑定current-change事件,此事件是分页条组件自己定义的事件,当页码改变时触发,对应的处理函数为handleCurrentChange
定义handleCurrentChange方法
4.2 后台代码
4.2.1 Controller
在CheckItemController中增加分页查询方法
4.2.2 服务接口
在CheckItemService服务接口中扩展分页查询方法
4.2.3 服务实现类
在CheckItemServiceImpl服务实现类中实现分页查询方法,基于Mybatis分页助手插件实现分页
4.2.4 Dao接口
在CheckItemDao接口中扩展分页查询方法
4.2.5 Mapper映射文件
在CheckItemDao.xml文件中增加SQL定义
5.1 完善页面
为了防止用户误操作,点击删除按钮时需要弹出确认删除的提示,用户点击取消则不做任何操作,用户点击确定按钮再提交删除请求。
5.1.1 绑定单击事件
需要为删除按钮绑定单击事件,并且将当前行数据作为参数传递给处理函数
5.1.2 弹出确认操作提示
用户点击删除按钮会执行handleDelete方法,此处需要完善handleDelete方法,弹出确认提示信息。ElementUI提供了$confirm方法来实现确认提示信息弹框效果
5.1.3 发送请求
如果用户点击确定按钮就需要发送ajax请求,并且将当前检查项的id作为参数提交到后台进行删除操作
5.2 后台代码
5.2.1 Controller
在CheckItemController中增加删除方法
5.2.2 服务接口
在CheckItemService服务接口中扩展删除方法
5.2.3 服务实现类
注意:不能直接删除,需要判断当前检查项是否和检查组关联,如果已经和检查组进行了关联则不允许删除
5.2.4 Dao接口
在CheckItemDao接口中扩展方法findCountByCheckItemId和deleteById
5.2.5 Mapper映射文件
在CheckItemDao.xml中扩展SQL语句
6.1 完善页面
用户点击编辑按钮时,需要弹出编辑窗口并且将当前记录的数据进行回显,用户修改完成后点击确定按钮将修改后的数据提交到后台进行数据库操作。
6.1.1 绑定单击事件
需要为编辑按钮绑定单击事件,并且将当前行数据作为参数传递给处理函数
6.1.2 弹出编辑窗口回显数据
当前页面中的编辑窗口已经提供好了,默认处于隐藏状态。在handleUpdate方法中需要将编辑窗口展示出来,并且需要发送ajax请求查询当前检查项数据用于回显
6.1.3 发送请求
在编辑窗口中修改完成后,点击确定按钮需要提交请求,所以需要为确定按钮绑定事件并提供处理函数handleEdit
6.2 后台代码
6.2.1 Controller
在CheckItemController中增加编辑方法
6.2.2 服务接口
在CheckItemService服务接口中扩展编辑方法
6.2.3 服务实现类
在CheckItemServiceImpl实现类中实现编辑方法
6.2.4 Dao接口
在CheckItemDao接口中扩展edit方法
6.2.5 Mapper映射文件
在CheckItemDao.xml中扩展SQL语句
1.1 介绍
在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
文件服务器:负责存储用户上传文件的服务器
[外链图片转存中…(img-Zje7YR6y-1653196547514)]
分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。
常见的图片存储方案:
方案一:使用nginx搭建图片服务器
方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等
方案三:使用云存储,例如阿里云、七牛云等
1.2 七牛云存储
七牛云(隶属于上海七牛信息技术有限公司)是国内领先的以视觉智能和数据智能为核心的企业级云计算服务商,同时也是国内知名智能视频云服务商,累计为 70 多万家企业提供服务,覆盖了国内80%网民。围绕富媒体场景推出了对象存储、融合 CDN 加速、容器云、大数据平台、深度学习平台等产品、并提供一站式智能视频云解决方案。为各行业及应用提供可持续发展的智能视频云生态,帮助企业快速上云,创造更广阔的商业价值。
官网:https://www.qiniu.com/
通过七牛云官网介绍我们可以知道其提供了多种服务,我们主要使用的是七牛云提供的对象存储服务来存储图片。
1.2.1 注册、登录
要使用七牛云的服务,首先需要注册成为会员。地址:https://portal.qiniu.com/signup
[外链图片转存中…(img-QJeDB2Fm-1653196547515)]
注册完成后就可以使用刚刚注册的邮箱和密码登录到七牛云:
[外链图片转存中…(img-Qlr6CpMX-1653196547515)]
登录成功后点击页面右上角管理控制台:
[外链图片转存中…(img-VvwWRodn-1653196547516)]
注意:登录成功后还需要进行实名认证才能进行相关操作。
1.2.2 新建存储空间
要进行图片存储,我们需要在七牛云管理控制台新建存储空间。点击管理控制台首页对象存储下的立即添加按钮,页面跳转到新建存储空间页面:
[外链图片转存中…(img-OZS547qN-1653196547517)]
可以创建多个存储空间,各个存储空间是相互独立的。
1.2.3 查看存储空间信息
存储空间创建后,会在左侧的存储空间列表菜单中展示创建的存储空间名称,点击存储空间名称可以查看当前存储空间的相关信息
[外链图片转存中…(img-73szfrod-1653196547518)]
1.2.4 开发者中心
可以通过七牛云提供的开发者中心学习如何操作七牛云服务,地址:https://developer.qiniu.com/
[外链图片转存中…(img-QwLhCl2q-1653196547518)]
点击对象存储,跳转到对象存储开发页面,地址:https://developer.qiniu.com/kodo
[外链图片转存中…(img-wXd97Eyx-1653196547519)]
七牛云提供了多种方式操作对象存储服务,本项目采用Java SDK方式,地址:https://developer.qiniu.com/kodo/sdk/1239/java
[外链图片转存中…(img-l3guIBHd-1653196547520)]
使用Java SDK操作七牛云需要导入如下maven坐标:
1.2.5 鉴权
Java SDK的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的Access Key和Secret Key,这对密钥可以在七牛云管理控制台的个人中心(https://portal.qiniu.com/user/key)获得,如下图:
[外链图片转存中…(img-w1Qd9Tap-1653196547521)]
1.2.6 Java SDK操作七牛云
本章节我们就需要使用七牛云提供的Java SDK完成图片上传和删除,我们可以参考官方提供的例子。
1.2.7 封装工具类
为了方便操作七牛云存储服务,我们可以将官方提供的案例简单改造成一个工具类,在我们的项目中直接使用此工具类来操作就可以:
将此工具类放在health_common工程中,后续会使用到。
2.1 需求分析
套餐其实就是检查组的集合,例如有一个套餐为“入职体检套餐”,这个体检套餐可以包括多个检查组:一般检查、血常规、尿常规、肝功三项等。所以在添加套餐时需要选择这个套餐包括的检查组。
套餐对应的实体类为Setmeal,对应的数据表为t_setmeal。套餐和检查组为多对多关系,所以需要中间表t_setmeal_checkgroup进行关联。
2.2 完善页面
套餐管理页面对应的是setmeal.html页面,根据产品设计的原型已经完成了页面基本结构的编写,现在需要完善页面动态效果。
2.2.1 弹出新增窗口
页面中已经提供了新增窗口,只是出于隐藏状态。只需要将控制展示状态的属性dialogFormVisible改为true接口显示出新增窗口。点击新建按钮时绑定的方法为handleCreate,所以在handleCreate方法中修改dialogFormVisible属性的值为true即可。同时为了增加用户体验度,需要每次点击新建按钮时清空表单输入项。
由于新增套餐时还需要选择此套餐包含的检查组,所以新增套餐窗口分为两部分信息:基本信息和检查组信息,如下图:
[外链图片转存中…(img-Hbf90OKl-1653196547522)]
[外链图片转存中…(img-bxF03CqD-1653196547522)]
新建按钮绑定单击事件,对应的处理函数为handleCreate
2.2.2 动态展示检查组列表
现在虽然已经完成了新增窗口的弹出,但是在检查组信息标签页中需要动态展示所有的检查组信息列表数据,并且可以进行勾选。具体操作步骤如下:
(1)定义模型数据
(2)动态展示检查组列表数据,数据来源于上面定义的tableData模型数据
(3)完善handleCreate方法,发送ajax请求查询所有检查组数据并将结果赋值给tableData模型数据用于页面表格展示
(4)分别在CheckGroupController、CheckGroupService、CheckGroupServiceImpl、CheckGroupDao、CheckGroupDao.xml中扩展方法查询所有检查组数据
CheckGroupController:
CheckGroupService:
CheckGroupServiceImpl:
CheckGroupDao:
CheckGroupDao.xml:
2.2.3 图片上传并预览
此处使用的是ElementUI提供的上传组件el-upload,提供了多种不同的上传效果,上传成功后可以进行预览。
实现步骤:
(1)定义模型数据,用于后面上传文件的图片预览:
(2)定义上传组件:
(3)定义对应的钩子函数:
(4)创建SetmealController,接收上传的文件
注意:别忘了在spring配置文件中配置文件上传组件
2.2.4 提交请求
当用户点击新增窗口中的确定按钮时发送ajax请求将数据提交到后台进行数据库操作。提交到后台的数据分为两部分:套餐基本信息(对应的模型数据为formData)和检查组id数组(对应的模型数据为checkgroupIds)。
为确定按钮绑定单击事件,对应的处理函数为handleAdd
完善handleAdd方法
2.3 后台代码
2.3.1 Controller
在SetmealController中增加方法
2.3.2 服务接口
创建SetmealService接口并提供新增方法
2.3.3 服务实现类
创建SetmealServiceImpl服务实现类并实现新增方法
2.3.4 Dao接口
创建SetmealDao接口并提供相关方法
2.3.5 Mapper映射文件
创建SetmealDao.xml文件并定义相关SQL语句
2.4 完善文件上传
前面我们已经完成了文件上传,将图片存储在了七牛云服务器中。但是这个过程存在一个问题,就是如果用户只上传了图片而没有最终保存套餐信息到我们的数据库,这时我们上传的图片就变为了垃圾图片。对于这些垃圾图片我们需要定时清理来释放磁盘空间。这就需要我们能够区分出来哪些是垃圾图片,哪些不是垃圾图片。如何实现呢?
方案就是利用redis来保存图片名称,具体做法为:
1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources
2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources
3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可
本小节我们先来完成前面2个环节,第3个环节(清理图片环节)在后面会通过定时任务再实现。
实现步骤:
(1)在health_backend项目中提供Spring配置文件spring-redis.xml
(2)在health_common工程中提供Redis常量类
(3)完善SetmealController,在文件上传成功后将图片名称保存到redis集合中
(4)在health_service_provider项目中提供Spring配置文件applicationContext-redis.xml
(5)完善SetmealServiceImpl服务类,在保存完成套餐信息后将图片名称存储到redis集合中
3.1 完善页面
3.1.1 定义分页相关模型数据
3.1.2 定义分页方法
在页面中提供了findPage方法用于分页查询,为了能够在setmeal.html页面加载后直接可以展示分页数据,可以在VUE提供的钩子函数created中调用findPage方法
3.1.3 完善分页方法执行时机
除了在created钩子函数中调用findPage方法查询分页数据之外,当用户点击查询按钮或者点击分页条中的页码时也需要调用findPage方法重新发起查询请求。
为查询按钮绑定单击事件,调用findPage方法
为分页条组件绑定current-change事件,此事件是分页条组件自己定义的事件,当页码改变时触发,对应的处理函数为handleCurrentChange
定义handleCurrentChange方法
3.2 后台代码
3.2.1 Controller
在SetmealController中增加分页查询方法
3.2.2 服务接口
在SetmealService服务接口中扩展分页查询方法
3.2.3 服务实现类
在SetmealServiceImpl服务实现类中实现分页查询方法,基于Mybatis分页助手插件实现分页
3.2.4 Dao接口
在SetmealDao接口中扩展分页查询方法
3.2.5 Mapper映射文件
在SetmealDao.xml文件中增加SQL定义
4.1 Quartz介绍
Quartz是Job scheduling(作业调度)领域的一个开源项目,Quartz既可以单独使用也可以跟spring框架整合使用,在实际开发中一般会使用后者。使用Quartz可以开发一个或者多个定时任务,每个定时任务可以单独指定执行的时间,例如每隔1小时执行一次、每个月第一天上午10点执行一次、每个月最后一天下午5点执行一次等。
官网:http://www.quartz-scheduler.org/
maven坐标:
4.2 Quartz入门案例
本案例基于Quartz和spring整合的方式使用。具体步骤:
(1)创建maven工程quartzdemo,导入Quartz和spring相关坐标,pom.xml文件如下
(2)自定义一个Job
(3)提供Spring配置文件spring-jobs.xml,配置自定义Job、任务描述、触发器、调度工厂等
(4)编写main方法进行测试
执行上面main方法观察控制台,可以发现每隔10秒会输出一次,说明每隔10秒自定义Job被调用一次。
4.3 cron表达式
上面的入门案例中我们指定了一个表达式:0/10 * * * * ?
这种表达式称为cron表达式,通过cron表达式可以灵活的定义出符合要求的程序执行的时间。本小节我们就来学习一下cron表达式的使用方法。如下图:
[外链图片转存中…(img-KKOYzI97-1653196547524)]
cron表达式分为七个域,之间使用空格分隔。其中最后一个域(年)可以为空。每个域都有自己允许的值和一些特殊字符构成。使用这些特殊字符可以使我们定义的表达式更加灵活。
下面是对这些特殊字符的介绍:
逗号(,):指定一个值列表,例如使用在月域上1,4,5,7表示1月、4月、5月和7月
横杠(-):指定一个范围,例如在时域上3-6表示3点到6点(即3点、4点、5点、6点)
星号(*):表示这个域上包含所有合法的值。例如,在月份域上使用星号意味着每个月都会触发
斜线(/):表示递增,例如使用在秒域上0/15表示每15秒
问号(?):只能用在日和周域上,但是不能在这两个域上同时使用。表示不指定
井号(#):只能使用在周域上,用于指定月份中的第几周的哪一天,例如6#3,意思是某月的第三个周五 (6=星期五,3意味着月份中的第三周)
L:某域上允许的最后一个值。只能使用在日和周域上。当用在日域上,表示的是在月域上指定的月份的最后一天。用于周域上时,表示周的最后一天,就是星期六
W:W 字符代表着工作日 (星期一到星期五),只能用在日域上,它用来指定离指定日的最近的一个工作日
4.4 cron表达式在线生成器
前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些cron表达式在线生成器来根据我们的需求生成表达式即可。
http://cron.qqe2.com/
[外链图片转存中…(img-0tyulS7A-1653196547525)]
前面我们已经完成了体检套餐的管理,在新增套餐时套餐的基本信息和图片是分两次提交到后台进行操作的。也就是用户首先将图片上传到七牛云服务器,然后再提交新增窗口中录入的其他信息。如果用户只是上传了图片而没有提交录入的其他信息,此时的图片就变为了垃圾图片,因为在数据库中并没有记录它的存在。此时我们要如何处理这些垃圾图片呢?
解决方案就是通过定时任务组件定时清理这些垃圾图片。为了能够区分出来哪些图片是垃圾图片,我们在文件上传成功后将图片保存到了一个redis集合中,当套餐数据插入到数据库后我们又将图片名称保存到了另一个redis集合中,通过计算这两个集合的差值就可以获得所有垃圾图片的名称。
本章节我们就会基于Quartz定时任务,通过计算redis两个集合的差值找出所有的垃圾图片,就可以将垃圾图片清理掉。
操作步骤:
(1)创建maven工程health_jobs,打包方式为war,导入Quartz等相关坐标
(2)配置web.xml
(3)配置log4j.properties
(4)配置applicationContext-redis.xml
(5)配置applicationContext-jobs.xml
(6)创建ClearImgJob定时任务类
前面我们已经完成了检查项管理、检查组管理、套餐管理等。接下来我们需要进行预约设置,其实就是设置每一天的体检预约最大数量。客户可以通过微信端在线预约,在线预约时需要选择体检的时间,如果客户选择的时间已经预约满则无法进行预约。
2.1 POI介绍
Apache POI是用Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。
jxl:专门操作Excel
maven坐标:
POI结构:
2.2 入门案例
2.2.1 从Excel文件读取数据
使用POI可以从一个已经存在的Excel文件中读取数据
通过上面的入门案例可以看到,POI操作Excel表格封装了几个核心对象:
上面案例是通过遍历工作表获得行,遍历行获得单元格,最终获取单元格中的值。
还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象,代码如下:
2.2.2 向Excel文件写入数据
使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘
预约设置信息对应的数据表为t_ordersetting,预约设置操作对应的页面为ordersetting.html
t_ordersetting表结构:
[外链图片转存中…(img-n96so3g4-1653196547525)]
orderDate:预约日期
number:可预约人数
reservations:已预约人数
批量导入预约设置信息操作过程:
1、点击模板下载按钮下载Excel模板文件
2、将预约设置信息录入到模板文件中
3、点击上传文件按钮将录入完信息的模板文件上传到服务器
4、通过POI读取上传文件的数据并保存到数据库
3.1 完善页面
3.1.1 提供模板文件
资料中已经提供了Excel模板文件ordersetting_template.xlsx,将文件放在health_backend工程的template目录
3.1.2 实现模板文件下载
为模板下载按钮绑定事件实现模板文件下载
3.1.3 文件上传
使用ElementUI的上传组件实现文件上传并绑定相关事件
3.2 后台代码
3.2.1 Controller
将资料中的POIUtils工具类复制到health_common工程
在health_backend工程创建OrderSettingController并提供upload方法
3.2.2 服务接口
创建OrderSettingService服务接口并提供新增方法
3.2.3 服务实现类
创建服务实现类OrderSettingServiceImpl并实现新增方法
3.2.4 Dao接口
创建Dao接口OrderSettingDao并提供更新和新增方法
3.2.5 Mapper映射文件
创建Mapper映射文件OrderSettingDao.xml并提供相关SQL
前面已经完成了预约设置功能,现在就需要通过日历的方式展示出来每天设置的预约人数。
在页面中已经完成了日历的动态展示,我们只需要查询当前月份的预约设置信息并展示到日历中即可,同时在日历中还需要展示已经预约的人数,效果如下:
[外链图片转存中…(img-LMLEIR8U-1653196547526)]
4.1 完善页面
4.1.1 使用静态数据调试
为了能够快速看到效果,我们可以先使用静态数据模拟,然后再改为发送ajax请求查询数据库。
实现步骤:
(1)预约设置数据对应的模型数据为leftobj,在initData方法最后为leftobj模型数据赋值:
其中date表示日期,number表示可预约人数,reservations表示已预约人数
(2)使用VUE的v-for标签遍历上面的leftobj模型数据,展示到日历上:
4.1.2 发送ajax获取动态数据
将上面的静态模拟数据去掉,改为发送ajax请求,根据当前页面对应的月份查询数据库获取预约设置信息,将查询结果赋值给leftobj模型数据
4.2 后台代码
4.2.1 Controller
在OrderSettingController中提供getOrderSettingByMonth方法,根据月份查询预约设置信息
4.2.2 服务接口
在OrderSettingService服务接口中扩展方法getOrderSettingByMonth
4.2.3 服务实现类
在OrderSettingServiceImpl服务实现类中实现方法getOrderSettingByMonth
4.2.4 Dao接口
在OrderSettingDao接口中扩展方法getOrderSettingByMonth
4.2.5 Mapper映射文件
在OrderSettingDao.xml文件中扩展SQL
本章节要完成的功能为通过点击日历中的设置按钮来设置对应日期的可预约人数。效果如下:
[外链图片转存中…(img-S98o8Db6-1653196547527)]
5.1 完善页面
5.1.1 为设置按钮绑定事件
为日历中的设置按钮绑定单击事件,当前日期作为参数
5.1.2 弹出预约设置窗口并发送ajax请求
完善handleOrderSet方法,弹出预约设置窗口,用户点击确定按钮则发送ajax请求
5.2 后台代码
5.2.1 Controller
在OrderSettingController中提供方法editNumberByDate
5.2.2 服务接口
在OrderSettingService服务接口中提供方法editNumberByDate
5.2.3 服务实现类
在OrderSettingServiceImpl服务实现类中实现editNumberByDate
5.2.4 Dao接口
在OrderSettingDao接口中提供方法
5.2.5 Mapper映射文件
在OrderSettingDao.xml映射文件中提供SQL