> 文章列表 > 传智健康-day2

传智健康-day2

传智健康-day2

一.需求分析(预约管理功能开发)

预约管理功能,包括检查项管理、检查组管理、体检套餐管理、预约设置等、预约管理属于系统的基础功能,主要就是管理一些体检的基础数据。  

检查组是检查项的集合

二.基础环境搭建

1导入预约管理模块数据表

需要用到的表和其中的关联表,检查项和检查组是多对多关系

2导入实体类POJO

根据数据表也可以自己创建实体类,两者存在对应关系,一张表对应一个实体类(POJO),关联表不存在实体类。

实体类之间存在多对多关系,可以通过在实体类中建立一个List集合来对应关系。

因为使用到检查组时一定会检索到检查组,所以在检查组中声明了检查项。

但是使用检查项时不一定会使用到检查组,所以检查项中没必要声明检查组

各个模块都有可能使用到这些实体类,将POJO实体类复制到health_common工程中

创建新的包pojo

3导入项目所需公共资源 

消息常量类

返回结果Result和PageResult(分页查询返回的结果类)类,放到health_common工程中

注:返回结果指的是SpringMVC中controller的返回结果,项目中所有的增删改查操作发送的请求,基于的都是ajax异步请求(可以用F12查看过程),请求完成后,在controller中处理,完成后controller将结果封装成PageResult对象,PageResult对象将结果转换成json数据,写回到前端页面。

Result类是除了分页查询返回结果类的所有返回结果类

QueryPageBean类,封装查询条件,页面输入的查询条件作为类的参数

创建新的包entity

4导入前端静态资源

复制资源包到health_backend模块下的webapp中

注:此处js资源中的axios.js文件是使用ajax必须的文件,vue.js文件是使用vue必须的文件

启动项目,因为项目依赖zookeeper基础服务,所以需要安装windows单机的zookeeper

三.zookeeper安装使用

zookeeper是apache hadoop项目下的一个子项目,是一个树形管理目录

zookeeper是一个分布式,开源的分布式应用程序的协调服务

主要功能是:配置管理,分布式锁,集群管理

目前开发阶段需要依赖zookeeper,但是不需要启动虚拟机,所以我们直接下载文件在windows环境下运行即可。

windows环境下安装zookeeper

1.首先去官网下载文件

2.解压到常用安装软件目录

3.运行zkServer.cmd文件

执行闪退:编辑zkServer.cmd末尾添加pause 。这样运行出错就不会退出,会提示错误信息,方便找到原因。 

缺少zoo.cfg文件:将conf目录下的zoo_sample.cfg文件,复制一份,重命名为zoo.cfg。

如果

出现ZooKeeper audit is disabled,zoo.cfg新增一行

audit.enable=true

成功启动后可以在logs目录中查看日志

四.分析页面结构

项目运行之前,对项目整体进行编译

因为在backend项目中的pom文件中引入了tomcat7,所以在backend的plugins中可以看到插件

如果pom文件中tomcat爆红,可以添加一个版本号

启动tomcat 

根据tomcat定义来确认访问路径

成功访问

iframe标签可以直接引用其它页面。

menuList可以遍历出所有的子级菜单

menuList中的linkUrl对应页面名称,点击菜单的时候就可以跳转到相关页面

通过href超链接跳转,linkUrl对应了页面名 

五.新增检查项-完善页面-弹出新增窗口

新建检查项功能应该在点击新建后弹出弹层,所以在默认情况下该弹层是隐藏的,单击新增后展示此页面

<el-dialog title="新增检查项" :visible.sync="dialogFormVisible">

visible.sync表示控制当前窗口是显示还是隐藏,:visible.sync表示绑定的控制值是动态的。

diaglogFormVisible是在vue对象中创建的一个模型数据

dialogFormVisible: false,//增加表单是否可见

默认值为false,表示默认此弹层不可见

为新建按钮绑定一个单击事件(@Click),对应的函数是handleCreate()

<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
// 弹出添加窗口
handleCreate() {},

当单击新建按钮时,触发对应函数handleCreate(),此时修改:visible.sync对应的控制值diaglogFormVisible发生变化,使弹层展示

handleCreate() {// 弹出新增页面this.dialogFormVisible=true;},

 取消按钮绑定的事件,把模型数据修改为false,从而使弹层取消展示

<el-button @click="dialogFormVisible4Edit = false">取消</el-button>

el-diaglog自带的×按钮也可以取消弹层展示

取消弹层展示后清空表单内容

表单输入框的内容和模型数据V-model绑定了,每次弹出之后,重新设置模型数据值,将数据值设置为空的json即可实现清空表单内容功能。

// 重置表单resetForm() {//重置表单数据this.formData = {};},
// 弹出添加窗口handleCreate() {// 弹出新增页面this.dialogFormVisible=true;//将json数据直接赋空值:{}this.formData = {};},

这样做可以重置表单,但是弹出新增功能就和重置表单功能粘合了,我们的原则是方法单一,即每个方法只完成一个功能。重置表单功能作为单一的一个方法,我们需要用到这个功能时直接调用这个方法即可。

六.新增检查项_输入校验

在VUE对象中定义校验规则(rules)

rules: {//校验规则code: [{ required: true, message: '项目编码为必填项', trigger: 'blur' }],name: [{ required: true, message: '项目名称为必填项', trigger: 'blur' }]
}

在以下输入域中应用规则

七.新增检查项_提交表单数据

提交表单数据使用ajax异步请求方式提交,点击提交按钮后,首先对表单数据进行一个整体校验,校验成功后,将表单数据获取,表单数据都绑定在VUE对象的模型数据(formData)中了。所以提交表单就是提交formData,发送ajax请求。

注:alter();方法可以检验触发事件@handleAdd

1.表单校验

// 1.表单校验,获取表单对象refsthis.$refs["dataAddForm"].validate((valid) => {alert(valid);});

表单数据对应的ref="dataAddForm",通过this.refs获取到表单数据,validate方法是一个箭头函数,如果表单校验通过,那么其中的valid值会是ture值。

 

controller端收到网页请求后,会产生一个响应(res),而在之前common模块中,已经封装好了controller的返回结果,定义res是一个Reslut类型的java对象,SpringMVC会自动将Result对象转化成json,flag,message。

// console.log(this.formData); //通过开发者模式观察通过校验后的表单数据
//添加handleAdd () {alert();// 1.表单校验,获取表单对象refsthis.$refs['dataAddForm'].validate((valid) => {if(valid) {// 表单检验通过,发送Ajax请求,将录入的数据提交到后台进行处理// console.log(this.formData); //通过开发者模式观察通过校验后的表单数据//引用axios文件来发送Ajax请求,post(请求地址,请求体(json数据)),发送后需要一个回调函数then,res是服务端(controller)响应的结果axios.post("/checkitem/add.do",this.formData).then((res) =>{//Result对象中包含的flag属性,res.data是固定写法,拿到的就是controller响应的数据//表单提交后,无论添加成功或者失败,都关闭新增窗口this.dialogFormVisible = false;if(res.data.flag){//执行成功//调用分页查询方法,查询出最新的数据this.findPage();//弹出提示信息this.$message({message:res.data.message,type:'success'});}else{//执行失败//弹出提示this.$message.error(res.data.message);}});}else{//校验不通过this.$message.error("数据校验失败,请检查输入信息是否正确");return false;}});},

res.data是一个固定写法

如果controller端没有响应,则不涉及到Result类的调用,则没有res.data的使用。直接使用 this.$message.*来展示返回结果即可

八.新增检查项_后台代码

一.定义Controller(backend)

在backend模块下新建controller路径,路径下新建CheckItemController类

controller用来响应前端发送的ajax请求

1.添加注解

@RestController
//@RestController包含@Controller注解,同时包含ResponseBody;直接让方法返回java对象,SpringMVC框架会自动将java对象转化成json.
@RequestMapping("/checkitem")
//匹配请求路径

 请求路径和前端发送请求的路径对应 

public void add(CheckItem checkItem);

2.添加对应的方法

方法中也要加一个注解匹配请求路径,对应前端的请求路径

@RequestMapping("/add")//匹配请求public Result add(@RequestBody CheckItem checkItem){}

 //此controller对应实体类是CheckItem,所以方法的参数是CheckItem。前端提交的formData是json数据,SpringMVC无法封装,需要加一个注解才能封装json数据;@RequestBody解析提交的数据,封装成CheckItem对象

3.调用服务层接口

@Reference//zookeeper服务中心去查找CheckItemService的服务private CheckItemService checkItemService;

4.调用接口对应的方法

checkItemService.add(checkItem);

5.检验调用是否成功

使用try-catch来验证是否调用服务层成功

try{checkItemService.add(checkItem);}catch(Exception e){e.printStackTrace();//服务调用失败return new Result(false, MessageConstant.ADD_CHECKITEM_FAIL);}return new Result(true, MessageConstant.ADD_CHECKITEM_SUCCESS);

二.定义服务层

服务层就是dubbo服务层,这个层级用来将controller处理过的前端提交的数据保存到数据库中

1.定义服务接口(interface)

2.声明接口方法

public void add(CheckItem checkItem);

3.定义服务实现类(service_provider) 

//发布服务,使用dubbo的服务注解
@Service(interfaceClass = CheckItemService.class)

4.注入DAO对象 

@Autowiredprivate CheckItemDao checkItemDao;

三.定义DAO层 

1.新建对应的dao接口

2.声明新增方法()

因为基于mybatis的动态代理方式,所以dao接口无需创建实现类,匹配一个xml映射文件即可

3.新建xml映射文件

 4.书写sql语句

头文件可以复制粘贴,sql语句的id对应dao接口中的方法名,parameterType(参数类型)必须和dao接口中指定的参数保持一致

mapper标签的namespace必须和dao接口的完整路径对应

​​<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.itheima.dao.CheckItemDao">
<!--    插入检查项数据--><insert id="add" parameterType="com.itheima.pojo.CheckItem" >insert into t_checkitem(code,name,sex,age,price,type,remark,attention)values(#{code},#{name},#{sex},#{age},#{price},#{type},#{remark},#{attention})</insert>
</mapper>

四.检查

配置文件中的参数,要让dubbo能够扫描到服务层

service实现类中的注解需要添加参数,因为添加了事务注解,所以@Service必须指明实现的是哪个接口

//事务注解
@Transactional
//发布服务,使用dubbo的服务注解
@Service(interfaceClass = CheckItemService.class)

五.运行准备

1.安装项目

2.启动服务层service_provider的tomcat

3.启动服务消费层backend的tomcat

4.运行网页端。

总结后台代码开发流程

九.检查项分页

1.分析检查项分页查询实现原理

项目所有分页功能都是基于ajax的异步请求来完成的,请求参数和后台响应数据格式都使用json数据格式。

前端的请求参数包括页码,每页显示记录数,查询条件

请求参数的json格式为:{currentPage:1,pageSize:10,queryString:''itcast''}

后台响应数据包括总记录数、当前页需要展示的数据集合。

响应数据的json格式为:{total:1000,rows:[]}

具体流程如下

2.完善页面

定义分页相关的模型数据 pagination

pagination: {//分页相关模型数据currentPage: 1,//当前页码pageSize:10,//每页显示的记录数total:0,//总记录数queryString:null//查询条件},dataList: [],//当前页要展示的分页列表数据

定义分页查询的方法findPage()

这个方法在页面加载完成时调用,可以使用钩子函数来完成,钩子函数:在VUE对象初始化完成后自动执行 

findPage() {//发送ajax请求,提交分页相关参数(页码,每页显示记录数,查询条件)var param = {currentPage:this.pagination.currentPage,pageSize:this.pagination.pageSize,queryString:this.pagination.queryString};//构造json对象,封装相关参数axios.post("checkitem/findPage.do",param).then((res) =>{//解析controller响应回的数据,为模型数据赋值,将响应回的数据赋给模型数据进行展示this.pagination.total = res.data.total;this.dataList = res.data.rows;});},

用户点击查询按钮或者点击分页条中的页码时也需要调用findPage方法重新发起查询请求。

为查询按钮绑定单击事件,调用findPage方法

当页码发生改变时,也要调用findPage()方法,分页条自带的事件@current-change,当页码发生改变时自动触发该事件,该事件绑定的方法可以使用传入页码参数(currentPage)和调用findPage()方法来实现页码改变和分页查询功能。

//切换页码handleCurrentChange(currentPage) {//设置最新的页码this.pagination.currentPage = currentPage;//调用findPage()方法进行分页查询this.findPage();},

总结:该方法的调用时机有:页面加载完成时,页码改变时,用户点击查询按钮时

十.检查项分页_后台代码

1.Controller

在checkItemController中添加对应的方法来接受前端的参数

参数是QueryPageBean

//检查项分页查询@RequestMapping("/findPage")//匹配请求public PageResult findPAge(@RequestBody QueryPageBean queryPageBean){PageResult pageResult = checkItemService.pageQuery(queryPageBean);return pageResult;}

2.服务接口

在checkItemService中添加对应方法

在checkItemController对应的方法中调用checkItemService中对应的方法

注:var快捷键可以快速实现代码书写,例如下

checkItemService.pageQuery(queryPageBean).var == PageResult pageResult = checkItemService.pageQuery(queryPageBean);

 然后将得到的参数pageResult返回

controller只是向dubbo服务调用了方法

3.服务实现类

在service的实现类中将分页查询方法拓展

4.Dao接口

在CheckItemDao接口中拓展出SQL对应方法

5.Mapper映射文件

mybatis框架了提供了分页助手插件,减少sql语句的书写量

没有分页助手插件情况下,sql语句实现分页查询,limit后面是页码和查询条数,这两个参数是动态的,根据currentPage和pageSize来计算

//select * from t_checkitem limit 0,10

使用分页助手插件后,不需手动书写limit后面的语句了,由助手进行自动拼接

在checkItemDAO.xml文件中新建SQL语句

<!--    页面有可能会传查询条件,使用动态where条件,如果有查询条件queryString,则查询。mybatis提供了动态sql--><select id="selectByCondition" parameterType="String" resultType="com.itheima.pojo.CheckItem">select * from t_checkitem<if test="value != null and value.length > 0">where code = #{value} or name = #{value}</if></select>

在服务实现类中调用CheckItemDao中的的方法 

十一.测试分页功能

关闭tomcat服务,对项目进行安装

十二.删除检查项_完善页面

删除操作需要缓冲空间,在点击删除后,弹出弹框再次确认是否删除。

ElementUI提供了$confirm方法来实现确认提示信息弹框效果

handleDelete(row) {//row对象是一个json对象,里面有//alert(row.id);this.$confirm("确定要删除这条数据吗?","提示",{type:"warning"}).then(()=>{//用户点击确定按钮,发送ajax请求,将要删除数据的id提交到controller进行处理axios.get("/checkitem/delete.do?id=" + row.id).then((res)=>{if(res.data.flag){//执行成功//弹出删除成功提示信息this.$message({type:"success",message:res.data.message});}else{//执行失败this.$message.error(res.data.message);}this.findPage();});}).catch(()=>{this.$message({type:"info",message:"操作取消"});});}

后台代码开发依据五个步骤:

1Controller(Backend)

2服务接口(interface)

3服务实现类(service_provider)

在实现类中定义实现方法:

代码逻辑:检查项和检查组之前存在n对m关系,检查项不能直接删除,需要判断当前检查项是否和检查组关联,如果已经和检查组进行了关联则不允许删除

4Dao接口(service_provider)

5Mapper映射文件(service_provider)

十三.编辑检查项

1.前端代码

绑定编辑单击事件,单击编辑时展示页面

// 弹出编辑窗口handleUpdate(row) {//显示窗口this.dialogFormVisible4Edit = true;//显示数据,发送ajax请求根据id查询当前检查项数据axios.get("/checkitem/findById.do?id=" + row.id).then((res) => {if(res.data.flag){//执行成功,进行回显,基于VUE的数据绑定来实现this.formData = res.data.data;}else{//查询失败,弹出提示this.$message.error(res.data.message);}});},

 编辑完成后,点击确定按钮进行提交,进行表单校验。

//编辑完成后确认handleEdit() {//表单校验this.$refs['dataEditForm'].validate((valid) => {if(valid){//表单校验通过,提交编辑后的数据axios.post("/checkitem/edit.do",this.formData).then((res) =>{if(res.data.flag){//判断本次操作是否成功//弹出成功信息this.$message({type:"success",message:res.data.message});}else{//本次操作失败this.$message.error(res.data.message);}}).finally(() =>{//finally方法不管成功还是失败都会执行this.findPage();//关闭编辑窗口this.dialogFormVisible4Edit = false;});}else{//表单校验失败,不提交this.$message.error("表单校验失败!");return false;//后面代码不执行}});},

axios自带的方法:

//finally方法不管成功还是失败都会执行

2.Controller

首先显示要编辑的数据

//显示要编辑的检查项@RequestMapping("/findById")//匹配请求public Result findById(Integer id){try{//查询应该存在一个返回对象,返回对象是checkItemCheckItem checkItem = checkItemService.findById(id);return new Result(true, MessageConstant.QUERY_CHECKITEM_SUCCESS,checkItem);}catch(Exception e){e.printStackTrace();//服务调用失败return new Result(false, MessageConstant.QUERY_CHECKITEM_FAIL);}}

再实现检查项的编辑更新

//编辑检查项@RequestMapping("/edit")//匹配请求public Result delete(@RequestBody CheckItem checkItem){try{checkItemService.edit(checkItem);}catch(Exception e){e.printStackTrace();//服务调用失败return new Result(false, MessageConstant.EDIT_CHECKGROUP_FAIL);}return new Result(true, MessageConstant.EDIT_CHECKGROUP_SUCCESS);}

3.服务接口interface

 

4.服务实现类Impl

声明实现方法后,调用Dao方法

 

5.Dao接口

声明方法

​​​​​​​ 

6.Mapper文件

使用动态sql来实现编辑操作,如果传过来的参数不为空,则将参数进行更新

至此检查项功能完成