1.预约管理的预约列表页面的显示
1.1显示分页页面功能
完成任务要求:实现预约内容的展示,新增和其他的这些操作暂时不写
实体类:
public class OrderList implements Serializable {
public static final String ORDERTYPE_TELEPHONE = "电话预约";
public static final String ORDERTYPE_WEIXIN = "微信预约";
public static final String ORDERSTATUS_YES = "已到诊";
public static final String ORDERSTATUS_NO = "未到诊";
private String fileNumber;//档案号
private String name;//姓名
private String phoneNumber;//手机号
private Date orderDate;//预约日期
private String orderType;//预约类型 电话预约/微信预约
private String orderStatus;//预约状态(是否到诊)
}
OrderSettingController :
@RestController
@RequestMapping("/ordersetting")
public class OrderSettingController {
@Reference
private OrderSettingService orderSettingService;//注入服务的接口
@Reference
private OrderService orderService;
//预约列表分页查询功能
@PreAuthorize("hasAuthority('CHECKITEM_QUERY')")//权限校验
@RequestMapping("/findPage")//使其那个被访问到
public PageResult findPage(@RequestBody QueryPageBean queryPageBean){
PageResult pageResult = orderService.pageQuery(queryPageBean);
System.out.println(pageResult.toString());
System.out.println(queryPageBean.toString());
return pageResult;//框架会将这个对象自动转换为JSON数据,响应回页面
}
}
OrderServiceImpl:
@Service(interfaceClass = OrderService.class)
@Transactional
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderSettingDao orderSettingDao;
@Autowired
private MemberDao memberDao;
@Autowired
private OrderDao orderDao;
//预约列表分页查询
public PageResult pageQuery(QueryPageBean queryPageBean) {
Integer currentPage = queryPageBean.getCurrentPage();//获取当前页面
Integer pageSize = queryPageBean.getPageSize();//要查询的数据,每页的记录数
String queryString = queryPageBean.getQueryString();//过滤条件/查询条件
//完成分页查询,基于mybatis框架提供的分页助手插件完成,现在不需要写sql语句(使用limit)
//现在只需要写limit前面的内容就可以了,limit之后的内容会自动追加
PageHelper.startPage(currentPage,pageSize);//不需要返回值,这个原理是使用线程实现的
//调用dao继续数据的操作
Page<OrderList> page = orderDao.selectByCondition(queryString);
long total = page.getTotal();
List<OrderList> rows = page.getResult();
return new PageResult(total,rows);
}
}
OrderDao.xml
<!--根据条件查询-->
<select id="selectByCondition" parameterType="string" resultType="com.yy.pojo.OrderList">
select
m.fileNumber, m.name,m.phoneNumber,
o.orderDate,o.orderType,o.orderStatus
from t_order o
INNER JOIN t_member m
on o.member_id = m.id
<if test="value != null and value.length > 0">
where fileNumber = #{value} or phoneNumber = #{value} or name = #{value}
</if>
</select>
1.2 新增预约功能实现
前台代码
ordersettinglist.html
<!-- 新增标签弹层 -->
<div class="add-form">
<el-dialog title="新增预约" :visible.sync="dialogFormVisible">
<template>
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="基本信息" name="first">
<el-form label-position="right" label-width="100px" :rules="rules" >
<el-row>
<el-col :span="12">
<el-form-item label="档案号" prop="fileNumber">
<el-input v-model="formData.fileNumber"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="手机号码" prop="phoneNumber">
<el-input v-model="formData.phoneNumber"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="预约时间" prop="orderDate">
<!-- <el-input v-model="formData.orderDate"/>-->
<el-date-picker type="date" v-model="formData.orderDate"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="预约类型" prop="orderType">
<el-select v-model="formData.orderType" >
<el-option label="微信预约" value="微信预约"></el-option>
<el-option label="电话预约" value="电话预约"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别">
<el-select v-model="formData.sex">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="formData.idCard"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="注意事项">
<el-input v-model="formData.attention" type="textarea"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-tab-pane>
<el-tab-pane label="套餐信息" name="second">
<div class="checkScrol">
<table class="datatable">
<thead>
<tr>
<th>选择</th>
<th>项目编码</th>
<th>项目名称</th>
<th>项目说明</th>
</tr>
</thead>
<tbody>
<tr v-for="c in tableData">
<td>
<input :id="c.id" v-model="checkSetmealId" type="radio" :value="c.id">
</td>
<td><label :for="c.id">{{c.code}}</label></td>
<td><label :for="c.id">{{c.name}}</label></td>
<td><label :for="c.id">{{c.remark}}</label></td>
</tr>
</tbody>
</table>
</div>
</el-tab-pane>
</el-tabs>
</template>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="handleAdd()">确定</el-button>
</div>
</el-dialog>
</div>
后台代码
OrderSettingController
@RequestMapping("/add")
//新增检查组
//因为checkitemIds传递过来的并不是json数据,所以不需要加@RequestBody
public Result add(@RequestBody OrderList orderList, Integer checkSetmealId){
Result result = null;
try {
result = orderService.add(orderList,checkSetmealId);
}catch (Exception e){
e.printStackTrace();
return new Result(false, MessageConstant.ORDERSETTING_FAIL);//新增失败
}
return new Result(true,MessageConstant.ORDERSETTING_SUCCESS);//新增成功
}
OrderServiceImpl
@Override
public Result add(OrderList orderList, Integer checkSetmealId) throws Exception{
//1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约
String orderDate = DateUtils.parseDate2String(orderList.getOrderDate());//预约日期
OrderSetting orderSetting= orderSettingDao.findByOrderDate(DateUtils.parseString2Date(orderDate));
if(orderSetting == null){
//指定日期没有进行预约设置,无法完成体检预约
return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
}
//2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约
int number = orderSetting.getNumber();//可预约人数
int reservations = orderSetting.getReservations();//已预约人数
if(reservations >= number){
//已经约满,无法预约
return new Result(false,MessageConstant.ORDER_FULL);//预约已满
}
//3、检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约则无法完成再次预约
String telephone = orderList.getPhoneNumber();//获取用户页面输入的手机号
Member member = memberDao.findByTelephone(telephone);
if(member != null){
//判断是否在重复预约
Integer memberId = member.getId();//会员ID
Date order_Date = DateUtils.parseString2Date(orderDate);//预约日期
Order order = new Order(memberId, order_Date, checkSetmealId);
//根据条件进行查询
List<Order> list = orderDao.findByCondition(order);
if(list != null && list.size() > 0){
//说明用户在重复预约,无法完成再次预约
return new Result(false,MessageConstant.HAS_ORDERED);
}
}else{
//4、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约
member = new Member();
member.setFileNumber(orderList.getFileNumber());
member.setName(orderList.getName());
member.setPhoneNumber(orderList.getPhoneNumber());
member.setIdCard(orderList.getIdCard());
member.setSex(orderList.getSex());
member.setRegTime(new Date());
member.setRemark(orderList.getRemark());
memberDao.add(member);//自动完成会员注册
}
//5、预约成功,更新当日的已预约人数,将当前的预约信息进行保存
Order order = new Order();
order.setMemberId(member.getId());//设置会员ID
order.setOrderDate(DateUtils.parseString2Date(orderDate));//预约日期
order.setOrderType(orderList.getOrderType());//预约类型
order.setOrderStatus(Order.ORDERSTATUS_NO);//到诊状态
order.setSetmealId(checkSetmealId);//套餐ID
orderDao.add(order);//将预约信息保存
orderSetting.setReservations(orderSetting.getReservations() + 1);//设置已预约人数+1
orderSettingDao.editReservationsByOrderDate(orderSetting);
return new Result(true,MessageConstant.ORDER_SUCCESS,order.getId());
}
1.3 设置当前预约状态为已到诊
前台代码
ordersettinglist.html
// 确认已到诊
handleUpdate(row) {
alert(row.phoneNumber);
//回显数据,通过发送ajax请求根据电话号码查询当前检查项数据
axios.get("/ordersetting/arrived.do?phoneNumber="+row.phoneNumber).then((res)=>{
//判断这个controller是否执行成功
if (res.data.flag){
//重新进行分页查询
this.findPage();
}else {
//查询失败,弹出提示
this.$message.error(res.data.message);
}
}).catch((r)=>{
this.showMessage(r);
});
},
后台代码
OrderSettingController
//根据id查询检查组
@RequestMapping("/arrived")
public Result arrived(String phoneNumber){
System.out.println("Controller里面的复选框的值:"+phoneNumber);
try {
orderService.arrived(phoneNumber);
}catch (Exception e){
e.printStackTrace();
return new Result(false, MessageConstant.ARRIVED_FAIL);//失败
}
return new Result(true,MessageConstant.ARRIVED_SUCCESS);//成功
}
OrderServiceImpl
@Override
public void arrived(String phoneNumber) {
Member member = memberDao.findByTelephone(phoneNumber);
Integer memberId = member.getId();//获取会员ID
orderDao.arrived(memberId);
}
1.4 取消(删除)当前预约
前台代码
ordersettinglist.html
// 取消
handleDelete(row) {//row其实是一个json对象,json对象中的数据为{"age":"0-100","attention":"无","code":"0007","id":34,"name":"裸视力(左)","price":5.0,"remark":"裸视力(左)","sex":"0","type":"1"}
// console.log(row);
alert(row.phoneNumber);
// alert(row.id);
this.$confirm("你确定要取消当前预约吗?","提示",{
type: 'warning'
}).then(()=>{
// alert("点击了确定按钮");
//用户点击确认按钮,发送ajax请求,将检查项提交到Controller进行处理
axios.get("/ordersetting/delete.do?phoneNumber="+row.phoneNumber).then((res)=>{
//判断是否执行成功
if (res.data.flag){
//执行成功
//弹出成功提示信息
this.$message({
type:'success',
message:res.data.message
});
//重新进行分页查询
this.findPage();
}else {
//执行失败
this.$message.error(res.data.message);
}
}).catch((r)=>{
this.showMessage(r);
});
}).catch(()=>{
// alert("点击了取消按钮");
this.$message({
type:'info',
message:'操作已取消'
});
});
}
后台代码
OrderSettingController
@RequestMapping("/delete")//使其那个被访问到
public Result delete(String phoneNumber){
//使用try。。catch。。进行成功还是失败判断
try{
System.out.println(phoneNumber);
orderService.deleteByPhoneNumber(phoneNumber);//如果调用失败就进入catch,没有失败就
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.ORDER_CANCEL_FAIL);
}
//证明删除成功
return new Result(true, MessageConstant.ORDER_CANCEL_SUCCESS);
}
OrderServiceImpl
@Override
public void deleteByPhoneNumber(String phoneNumber) {
Member member = memberDao.findByTelephone(phoneNumber);
Integer memberId = member.getId();//获取会员ID
orderDao.deleteById(memberId);
}
2.删除检查组功能的实现
删除是报错,因为有外键关联,所以需要级联删除
Cannot delete or update a parent row: a foreign key constraint fails (`health`.`t_checkgroup_checkitem`, CONSTRAINT `group_id` FOREIGN KEY (`checkgroup_id`) REFERENCES `t_checkgroup` (`id`))
最终解决代码:
CheckGroupController,controller代码与之前的区别不是很大
//删除检查组
@PreAuthorize("hasAuthority('CHECKITEM_DELETE')")//权限校验
@RequestMapping("/delete")//使其那个被访问到
public Result delete(Integer id){
//使用try。。catch。。进行成功还是失败判断
try{
System.out.println(id);
checkGroupService.deleteById(id);//如果调用失败就进入catch,没有失败就
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.DELETE_CHECKGROUP_FAIL);
}
//证明删除成功
return new Result(true, MessageConstant.DELETE_CHECKGROUP_SUCCESS);
}
CheckGroupServiceImpl
@Override
//删除检查组
public void deleteById(Integer id) {
//判断当前检查项是否关联到套餐表,关联了就不能删除
long count = checkGroupDao.findCountByCheckGroupId(id);
if (count > 0){
//当前检查组已经被关联到套餐,不允许被删除
throw new RuntimeException();
}else {
//清理当前检查组关联的检查项,操作中间关系表t_checkgroup_checkitem表
checkGroupDao.deleteAssocication(id);
//清理当前检查组关联的检查项,操作中间关系表t_setmeal_checkgroup表
checkGroupDao.deleteAssocicationSetmeal(id);
checkGroupDao.deleteById(id);
}
}
CheckGroupDao
//清理当前检查组关联的检查项,操作中间关系表t_checkgroup_checkitem表
public void deleteAssocication(Integer id);
//根据检查项的id查找中间表中是否有这个检查项,如果有(大于0)证明检查组中有这个检查项
public long findCountByCheckGroupId(Integer id);
//删除检查组
public void deleteById(Integer id);
//清理当前检查组关联的检查项,操作中间关系表t_setmeal_checkgroup表
public void deleteAssocicationSetmeal(Integer id);
CheckGroupDao.xml
<!--根据检查组ID清理关联的检查项信息,操作的表t_checkgroup_checkitem-->
<delete id="deleteAssocication" parameterType="int">
delete from t_checkgroup_checkitem where checkgroup_id = #{id}
</delete>
<!--根据检查组ID清理关联的套餐信息,操作的表t_setmeal_checkgroup-->
<delete id="deleteAssocicationSetmeal" parameterType="int">
delete from t_setmeal_checkgroup where checkgroup_id = #{id}
</delete>
<!--通过id删除检查组-->
<delete id="deleteById" parameterType="int">
delete from t_checkgroup where id = #{id}
</delete>
<!--根据检查组id查询中间关系表-->
<select id="findCountByCheckGroupId" resultType="long" parameterType="int">
select count(*) from t_setmeal_checkgroup where checkgroup_id = #{checkgroup_id}
</select>
3.套餐的编辑功能
前台代码
//编辑
handleEdit() {
//发送ajax请求,将修改后的表单数据(检查组基本信息、勾选的检查项)提交到后台进行处理
axios.post("/setmeal/edit.do?checkgroupIds="+this.checkgroupIds,this.formData).then((res)=>{
//关闭编辑窗口
console.log(this.checkitemIds);
this.dialogFormVisible4Edit = false;
if (res.data.flag){
//操作成功
this.$message({
type:'success',
message:res.data.message
});
}else{
//操作失败
this.$message.error(res.data.message);
}
}).catch((r)=>{
this.showMessage(r);
}).finally(()=>{
//不管成功或者是失败都要进行分页查询
this.findPage();
});
},
// 弹出编辑窗口
handleUpdate(row) {
// alert(row.id);
//弹出编辑窗口
this.dialogFormVisible4Edit = true;
//将弹出的窗口默认是first这个窗口
this.activeName = 'first';
//发送ajax请求,根据检查组ID查询当前检查组的数据,用于基本信息的回显
axios.get("/setmeal/findById.do?id="+row.id).then((res)=>{
if (res.data.flag){
//查询数据成功
this.formData = res.data.data;//赋值给formData进行页面的回显
} else {
//查询数据失败
this.$message.error(res.data.message);
}
});
//发送ajax请求,查询所有的检查项数据,用于展示检查项列表
axios.get("/checkgroup/findAll.do").then((res)=>{
if (res.data.flag){
//查询检查项数据成功
this.tableData = res.data.data;
//发送ajax请求,根据检查组ID查询当前检查组包含的检查项ID,用于页面复选框的回显
//java代码里面返回的是List<Integer>,将这个转换为JSON,获取的就是需要的效果
axios.get("/setmeal/findCheckGroupIdsBySetmealId.do?id="+row.id).then((res)=>{
if (res.data.flag){
this.checkgroupIds = res.data.data;
}else {
//查询检查项数据失败
this.$message.error(res.data.message);
}
});
}else {
//查询检查项数据失败
this.$message.error(res.data.message);
}
});
},
后台代码:
SetmealController
//编辑检查组
@RequestMapping("/edit")
@PreAuthorize("hasAuthority('CHECKGROUP_EDIT')")//权限校验
public Result edit(@RequestBody CheckGroup checkGroup,Integer[] checkitemIds){
try{
checkGroupService.edit(checkGroup,checkitemIds);
}catch (Exception e){
e.printStackTrace();
return new Result(false, MessageConstant.EDIT_CHECKGROUP_FAIL);//新增失败
}
return new Result(true,MessageConstant.EDIT_CHECKGROUP_SUCCESS);//新增成功
}
SetmealService
//编辑检查组
public void edit(CheckGroup checkGroup, Integer[] checkitemIds);
SetmealServiceImpl
@Override
//编辑套餐信息,同时需要关联检查组
public void edit(Setmeal setmeal, Integer[] checkgroupIds) {
//修改套餐本信息,操作检查组t_setmeal表
setmealDao.edit(setmeal);
//清理当前套餐关联的检查组,操作中间关系表t_setmeal_checkgroup表
setmealDao.deleteAssocication(setmeal.getId());
//重新建立当前套餐和检查组的关联关系
Integer checkGroupId = setmeal.getId();
this.setSetmealAndCheckgroup(checkGroupId,checkgroupIds);
}
SetmealDao
/**
* 清理当前套餐关联的检查组,操作中间关系表t_setmeal_checkgroup表
* @param id
*/
public void deleteAssocication(Integer id);
SetmealDao.xml
<!--根据ID动态修改套餐相关字段-->
<update id="edit" parameterType="com.yy.pojo.Setmeal">
update t_setmeal
<set>
<if test="name != null">
name = #{name},
</if>
<if test="sex != null">
sex = #{sex},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="price != null">
price = #{price},
</if>
<if test="code != null">
code = #{code},
</if>
<if test="helpCode != null">
helpCode = #{helpCode},
</if>
<if test="attention != null">
attention = #{attention},
</if>
<if test="remark != null">
remark = #{remark},
</if>
<if test="img != null">
img = #{img},
</if>
</set>
where id = #{id}
</update>
<!--清理当前套餐关联的检查组,操作中间关系表t_setmeal_checkgroup表-->
<delete id="deleteAssocication" parameterType="int">
delete from t_setmeal_checkgroup where setmeal_id = #{id}
</delete>
4.套餐的删除功能
前台代码
// 删除
handleDelete(row) {
// alert(row.id);
console.log(row);
this.$confirm("你确定要删除当前套餐吗?","提示",{
type: 'warning'
}).then(()=>{
// alert("点击了确定按钮");
//用户点击确认按钮,发送ajax请求,将检查项提交到Controller进行处理
axios.get("/setmeal/delete.do?id="+row.id).then((res)=>{
//判断是否执行成功
if (res.data.flag){
//执行成功
//弹出成功提示信息
this.$message({
type:'success',
message:res.data.message
});
//重新进行分页查询
this.findPage();
}else {
//执行失败
this.$message.error(res.data.message);
}
}).catch((r)=>{
this.showMessage(r);
});
}).catch(()=>{
// alert("点击了取消按钮");
this.$message({
type:'info',
message:'操作已取消'
});
});
}
后台代码:
SetmealController
//删除检查组
@PreAuthorize("hasAuthority('SETMEAL_DELETE')")//权限校验
@RequestMapping("/delete")//使其那个被访问到
public Result delete(Integer id){
//使用try。。catch。。进行成功还是失败判断
try{
System.out.println(id);
setmealService.deleteById(id);//如果调用失败就进入catch,没有失败就
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.DELETE_SETMEAL_FAIL);
}
//证明删除成功
return new Result(true, MessageConstant.DELETE_SETMEAL_SUCCESS);
}
SetmealService
/**
* 通过id删除套餐
* @param id
*/
public void deleteById(Integer id);
SetmealServiceImpl
@Override
//通过id删除套餐
public void deleteById(Integer id) {
//判断当前套餐id是否关联到套餐表,关联了就不能删除
long count = setmealDao.findCountBySetmealId(id);
if (count > 0){
//当前检查组已经被关联到套餐,不允许被删除
throw new RuntimeException(MessageConstant.DELETE_SETMEAL_FAIL);
}else {
//清理当前套餐id关联的order表,操作中间关系表t_order表
setmealDao.deleteAssocicationOrder(id);
//清理当前套餐关联的检查组,操作中间关系表t_setmeal_checkgroup表
setmealDao.deleteAssocication(id);
setmealDao.deleteById(id);
}
}
SetmealDao
/**
* 根据检查项的id查找中间表中是否有这个检查项,如果有(大于0)证明检查组中有这个检查项
* @param id
* @return
*/
public long findCountBySetmealId(Integer id);
/**
* 清理当前套餐id关联的order表,操作中间关系表t_order表
* @param id
*/
public void deleteAssocicationOrder(Integer id);
public void deleteById(Integer id);
SetmealDao.xml
<!--清理当前套餐关联的检查组,操作中间关系表t_setmeal_checkgroup表-->
<delete id="deleteAssocication" parameterType="int">
delete from t_setmeal_checkgroup where setmeal_id = #{id}
</delete>
<!--清理当前套餐id关联的order表,操作中间关系表t_order表-->
<delete id="deleteAssocicationOrder" parameterType="int">
delete from t_order where setmeal_id = #{id}
</delete>
<!--根据套餐id查询中间关系表-->
<select id="findCountBySetmealId" resultType="long" parameterType="int">
select count(*) from t_order where setmeal_id = #{setmeal_id}
</select>
<!--通过id删除检查组-->
<delete id="deleteById" parameterType="int">
delete from t_setmeal where id = #{id}
</delete>