医疗管理系统-体检预约

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 医疗管理系统-体检预约

1. 体检预约流程

用户可以通过如下操作流程进行体检预约:

  1. 在移动端首页点击体检预约,页面跳转到套餐列表页面
  2. 在套餐列表页面点击要预约的套餐,页面跳转到套餐详情页面
  3. 在套餐详情页面点击立即预约,页面跳转到预约页面
  4. 在预约页面录入体检人信息,包括手机号,点击发送验证码
  1. 在预约页面录入收到的手机短信验证码,点击提交预约,完成体检预约

2.体检预约

2.1 页面调整

在预约页面(/pages/orderInfo.html)进行调整

2.1.1 展示预约的套餐信息

第一步:从请求路径中获取当前套餐的id

<script>
  var id = getUrlParam("id");//套餐id
</script>

第二步:定义模型数据setmeal,用于套餐数据展示

var vue = new Vue({
        el: '#app',
        data: {
            setmeal: {},//套餐信息
            orderInfo: {
                setmealId: id,
                sex: '1'
            }//预约信息
        }
});
<div class="card">
   <div class="">
        <img :src="'http://pqjroc654.bkt.clouddn.com/'+setmeal.img" width="100%" height="100%"/>
    </div>
    <div class="project-text">
        <h4 class="tit">{{setmeal.name}}</h4>
        <p class="subtit">{{setmeal.remark}}</p>
        <p class="keywords">
            <span>{{setmeal.sex == '0' ? '性别不限' : setmeal.sex == '1' ? '男':'女'}}</span>
            <span>{{setmeal.age}}</span>
        </p>
    </div>
    <div class="project-know">
        <a href="orderNotice.html" class="link-page">
            <i class="icon-ask-circle"><span class="path1"></span><span class="path2"></span></i>
            <span class="word">预约须知</span>
            <span class="arrow"><i class="icon-rit-arrow"></i></span>
        </a>
    </div>
</div>

第三步:在VUE的钩子函数中发送ajax请求,根据id查询套餐信息

mounted(){
//发送ajax请求,获取套餐信息
  axios.post("/setmeal/findById.do?id=" + id).then((resp) => {
      if (resp.data.flag) {
          this.setmeal = resp.data.data;
      } else {
          this.$message.error(resp.data.message)
      }
  })
}

2.1.2 手机号校验

第一步:在页面导入的healthmobile.js文件中已经定义了校验手机号的方法

/**
* 手机号校验
1‐‐以1为开头;
2‐‐第二位可为3,4,5,7,8,中的任意一位;
3‐‐最后以0‐9的9个整数结尾。
*/
function checkTelephone(telephone) { 
  var reg=/^[1][3,4,5,7,8][0‐9]{9}$/; 
  if (!reg.test(telephone)) {
    return false;
  } else {
    return true;
  }
}

第二步:为发送验证码按钮绑定事件sendValidateCode

<div class="input‐row">
  <label>手机号</label>
  <input v‐model="orderInfo.telephone" type="text" class="input‐clear" placeholder="请输入手机号"> 
  <input style="font‐size: x‐small;" id="validateCodeButton" @click="sendValidateCode()" type="button" value="发送验证码">
</div>
12345
//发送验证码
sendValidateCode(){
  //获取用户输入的手机号
  var telephone = this.orderInfo.telephone;
  //校验手机号输入是否正确
  if (!checkTelephone(telephone)) {
    this.$message.error('请输入正确的手机号');
    return false;
  }
}

2.1.3 30秒倒计时效果

前面在sendValidateCode方法中进行了手机号校验,如果校验通过,需要显示30秒倒计时效果

//发送验证码
sendValidateCode(){
  //获取用户输入的手机号
  var telephone = this.orderInfo.telephone; //校验手机号输入是否正确
  if (!checkTelephone(telephone)) {
    this.$message.error('请输入正确的手机号');
    return false;
  }
  validateCodeButton = $("#validateCodeButton")[0]; 
  clock = window.setInterval(doLoop, 1000); //一秒执行一次
}

其中,validateCodeButton和clock是在healthmobile.js文件中定义的变量,doLoop是在healthmobile.js文件中定义的方法

var clock = '';//定时器对象,用于页面30秒倒计时效果 var nums = 30;
var validateCodeButton;
//基于定时器实现30秒倒计时效果
function doLoop() {
  validateCodeButton.disabled = true;//将按钮置为不可点击 nums‐‐;
  if (nums > 0) {
    validateCodeButton.value = nums + '秒后重新获取';
  } else {
    clearInterval(clock); //清除js定时器 
    validateCodeButton.disabled = false;    
    validateCodeButton.value = '重新获取验证码'; nums = 30; //重置时间
  }
}

2.1.4 发送ajax请求

在按钮上显示30秒倒计时效果的同时,需要发送ajax请求,在后台给用户发送手机验证码

//发送验证码
sendValidateCode(){
//获取用户输入的手机号
var telephone = this.orderInfo.telephone; //校验手机号输入是否正确
  if (!checkTelephone(telephone)) {
    this.$message.error('请输入正确的手机号');
  return false;
  }
  validateCodeButton = $("#validateCodeButton")[0]; 
  clock = window.setInterval(doLoop, 1000); //一秒执行一次 
  axios.post("/validateCode/send4Order.do?telephone=" +telephone).then((response) => {
    if(!response.data.flag){
      //验证码发送失败
      this.$message.error('验证码发送失败,请检查手机号输入是否正确');
    }
  });
}

创建ValidateCodeController,提供方法发送短信验证码,并将验证码保存到redis

package com.oldlu.controller;
import com.aliyuncs.exceptions.ClientException;
import com.oldlu.constant.MessageConstant;
import com.oldlu.constant.RedisMessageConstant;
import com.oldlu.entity.Result;
import com.oldlu.utils.SMSUtils;
import com.oldlu.utils.ValidateCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.JedisPool;
/**
 * 验证码管理
 *
 * @author oldlu
 * @version 1.0
 * @date 2019/10/21 15:29
 */
@RestController
@RequestMapping("/vaildateCode")
public class ValidateCodeController {
    @Autowired
    private JedisPool jedisPool;
    /**
     * 用户提交预约发送验证码
     *
     * @param telephone
     * @return
     */
    @RequestMapping("/send4Order")
    public Result send4Order(String telephone) {
        try {
            //给用户是否验证码
            //获取随机4位验证码
            Integer code = ValidateCodeUtils.generateValidateCode(4);
            //发送短信
            SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE, telephone, code.toString());
            //将验证码保存到redis(5分钟 )
            jedisPool.getResource().setex(telephone + RedisMessageConstant.SENDTYPE_ORDER, 500, code.toString());
            return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);
        } catch (ClientException e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);
        }
    }
}

2.1.5 日历展示

页面中使用DatePicker控件来展示日历。根据需求,最多可以提前一个月进行体检预约,所以日历控件只展示未来一个月的日期

<div class="date">
<label>体检日期</label>
<i class="icon‐date" class="picktime"></i>
<input v‐model="orderInfo.orderDate" type="text" class="picktime" readonly>
</div>
12345
<script>
//日期控件
var calendar = new datePicker();
calendar.init({
  'trigger': '.picktime',/*按钮选择器,用于触发弹出插件*/
  'type': 'date',/*模式:date日期;datetime日期时间;time时间;ym年月;*/
  'minDate': getSpecifiedDate(new Date(),1),/*最小日期*/
  'maxDate': getSpecifiedDate(new Date(),30),/*最大日期*/
  'onSubmit': function() { /*确认时触发事件*/},
  'onClose': function() { /*取消时触发事件*/ } });
</script>

其中getSpecifiedDate方法定义在healthmobile.js文件中

//获得指定日期后指定天数的日期
function getSpecifiedDate(date,days) {
  date.setDate(date.getDate() + days);//获取指定天之后的日期
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  var day = date.getDate();
  return (year + "‐" + month + "‐" + day);
}

2.1.6 提交预约请求

为提交预约按钮绑定事件

<div class="box‐button">
  <button @click="submitOrder()" type="button" class="btn order‐btn">提交预约</button>
</div>
123
//提交预约
submitOrder(){
  //校验身份证号格式
  if(!checkIdCard(this.orderInfo.idCard)){
    this.$message.error('身份证号码输入错误,请重新输入');
    return ;
  }
  axios.post("/order/submit.do",this.orderInfo).then((response) => { if(response.data.flag){
    //预约成功,跳转到预约成功页面
    window.location.href="orderSuccess.html?orderId=" + response.data.data;
  }else{
    //预约失败,提示预约失败信息
    this.$message.error(response.data.message);
  }
  });
}

其中checkIdCard方法是在healthmobile.js文件中定义的

/**
* 身份证号码校验
* 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
*/
function checkIdCard(idCard){
  var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; if(reg.test(idCard)){
    return true; 
  }else{
    return false;
  }
}
1234567891011

2.2 后台代码

2.2.1 Controller

在health_mobile工程中创建OrderController并提供submitOrder方法

package com.oldlu.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.aliyuncs.exceptions.ClientException;
import com.oldlu.constant.MessageConstant;
import com.oldlu.constant.RedisMessageConstant;
import com.oldlu.entity.Result;
import com.oldlu.pojo.Order;
import com.oldlu.service.OrderService;
import com.oldlu.utils.SMSUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.Map;
/**
 * 体检预约处理
 *
 * @author oldlu
 * @version 1.0
 * @date 2019/10/21 16:30
 */
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private JedisPool jedisPool;
    @Reference
    private OrderService orderService;
    @RequestMapping("submit")
    public Result submit(@RequestBody Map map) {
        String telephone = (String) map.get("telephone");
        String validateCode = (String) map.get("validateCode");
        if (telephone == null || validateCode == null) {
            return new Result(false, MessageConstant.TELEPHONE_VALIDATECODE_NOTNULL);
        }
        //Redis中获取保存的验证码
        String validateCodeInRedis = jedisPool.getResource().get(telephone + RedisMessageConstant.SENDTYPE_ORDER);
        //将用户输入的验证码和Redis中保存的验证码进行比对
        if (validateCodeInRedis != null && validateCodeInRedis.equals(validateCode)) {
            //如果对比成功,调用服务完成预约业务处理
            Result result = null;
            try {
                map.put("orderType", Order.ORDERTYPE_WEIXIN);
                result = orderService.order(map);
            } catch (Exception e) {
                e.printStackTrace();
                return result;
            }
            if (result.isFlag()) {
                //预约成功短信通知
                String orderDate = (String) map.get("orderDate");
                try {
                    SMSUtils.sendShortMessage(SMSUtils.ORDER_NOTICE, telephone, orderDate);
                } catch (ClientException e) {
                    e.printStackTrace();
                }
            }
            return result;
        } else {
            //如果比对不成功,返回结果给页面
            return new Result(false, MessageConstant.VALIDATECODE_ERROR);
        }
    }
}
  • SMSUtils
package com.oldlu.utils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
/**
 * 短信发送工具类
 */
public class SMSUtils {
    public static final String VALIDATE_CODE = "SMS_175532946";//发送短信验证码
    public static final String ORDER_NOTICE = "SMS_175582890";//体检预约成功通知
    /**
     * 发送短信
     *
     * @param phoneNumbers
     * @param param
     * @throws ClientException
     */
    public static void sendShortMessage(String templateCode, String phoneNumbers, String param) throws ClientException {
        // 设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        // 初始化ascClient需要的几个参数
        final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
        final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
        // 替换成你的AK
        final String accessKeyId = "";// 你的accessKeyId,
        final String accessKeySecret = "";// 你的accessKeySecret,
        // 初始化ascClient,暂时不支持多region(请勿修改)
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        // 组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        // 使用post提交
        request.setMethod(MethodType.POST);
        // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
        request.setPhoneNumbers(phoneNumbers);
        // 必填:短信签名-可在短信控制台中找到
        request.setSignName("XX健康");
        // 必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateCode);
        // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
        request.setTemplateParam("{\"code\":\"" + param + "\"}");
        // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
        // request.setSmsUpExtendCode("90997");
        // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        // request.setOutId("yourOutId");
        // 请求失败这里会抛ClientException异常
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
            // 请求成功
            System.out.println("请求成功");
        }
    }
}

2.2.2 服务接口

在health_interface工程中创建体检预约服务接口OrderService并提供预约方法

package com.oldlu.service;
import com.oldlu.entity.Result;
import java.util.Map;
/**
* 体检预约服务接口
*/
public interface OrderService {
  //体检预约
  public Result order(Map map) throws Exception;
}

2.2.3 服务实现类

在health_service_provider工程中创建体检预约服务实现类OrderServiceImpl并实现体检预约方法。

体检预约方法处理逻辑比较复杂,需要进行如下业务处理:

  1. 检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约
  2. 检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约
  3. 检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约则无法完成再次预约
  1. 检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约
  2. 预约成功,更新当日的已预约人数

实现代码如下:

package com.oldlu.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.oldlu.constant.MessageConstant;
import com.oldlu.dao.MemberDao;
import com.oldlu.dao.OrderDao;
import com.oldlu.dao.OrderSettingDao;
import com.oldlu.entity.Result;
import com.oldlu.pojo.Member;
import com.oldlu.pojo.Order;
import com.oldlu.pojo.OrderSetting;
import com.oldlu.service.OrderService;
import com.oldlu.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 体检预约服务
 *
 * @author oldlu
 * @version 1.0
 * @date 2019/10/21 22:28
 */
@Service(interfaceClass = OrderService.class)
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderSettingDao orderSettingDao;
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    /**
     * 体检预约
     *
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Result order(Map map) throws Exception {
        //1. 检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约
        String orderDate = (String) map.get("orderDate");
        Date orderTime = DateUtils.parseString2Date(orderDate);
        OrderSetting orderSetting = orderSettingDao.findByOrderDate(orderTime);
        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 = (String) map.get("telephone");
        Member member = memberDao.findByTelephone(telephone);
        if (member != null) {
            //判断是否重复预约
            Integer id = member.getId();
            Integer setmealId = (Integer) map.get("setmealId");
            Order order = new Order(setmealId, orderTime, setmealId);
            //根据条件进行查询
            List<Order> orderList = orderDao.findByCondition(order);
            if (orderList != null && orderList.size() > 0) {
                //说明用户在重复预约,无法完成再次预约
                return new Result(false, MessageConstant.HAS_ORDERED);
            }
        } else {
            //4. 检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约
            member = new Member();
            member.setName((String) map.get("name"));
            member.setPhoneNumber(telephone);
            member.setIdCard((String) map.get("idCard"));
            member.setSex((String) map.get("sex"));
            member.setRegTime(new Date());
            //自动完成会员注册
            memberDao.add(member);
        }
        //5. 预约成功,更新当日的已预约人数
        Order order = new Order();
        order.setMemberId(member.getId());
        order.setOrderDate(orderTime);
        order.setOrderType((String) map.get("orderType"));
        order.setSetmealId(Integer.parseInt((String) map.get("setmealId")));
        orderDao.add(order);
        //更新当日的已预约人数
        orderSetting.setReservations(orderSetting.getReservations()+1);
        orderSettingDao.editReservationsByOrderDate(orderSetting);
        return new Result(true,MessageConstant.ORDER_SUCCESS,order.getId());
    }
}

2.2.4 Dao接口

package com.oldlu.dao;
import com.oldlu.pojo.OrderSetting;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * @author oldlu
 * @version 1.0
 * @date 2019/10/18 20:17
 */
public interface OrderSettingDao {
    /**
     * 根据预约时间查询是否存在预约
     * @param orderDate
     * @return
     */
    public long findCountByOrderDate(Date orderDate);
    /**
     * 添加预约
     * @param orderSetting
     */
    public void add(OrderSetting orderSetting);
    /**
     * 根据预约时间修改预约人数
     * @param orderSetting
     */
    public void editNumberByOrderDate(OrderSetting orderSetting);
    /**
     * 根据月份查询对应的预约设置数据
     * @param map
     * @return
     */
    public List<OrderSetting> getOrderSettingByMonth(Map<String, String> map);
    /**
     * 根据时间查询预约设置信息
     * @param date
     * @return
     */
    public OrderSetting findByOrderDate(Date date);
    /**
     * 更新已预约人数
     * @param orderSetting
     */
    public void editReservationsByOrderDate(OrderSetting orderSetting);
}
package com.oldlu.dao;
import com.github.pagehelper.Page;
import com.oldlu.pojo.Member;
import java.util.List;
public interface MemberDao {
    public List<Member> findAll();
    public Page<Member> selectByCondition(String queryString);
    public void add(Member member);
    public void deleteById(Integer id);
    public Member findById(Integer id);
    public Member findByTelephone(String telephone);
    public void edit(Member member);
    public Integer findMemberCountBeforeDate(String date);
    public Integer findMemberCountByDate(String date);
    public Integer findMemberCountAfterDate(String date);
    public Integer findMemberTotalCount();
}
package com.oldlu.dao;
import com.oldlu.pojo.Order;
import java.util.List;
import java.util.Map;
public interface OrderDao {
  public List<Order> findByCondition(Order order);
}

2.2.5 Mapper映射文件

OrderSettingDao.xml

<!--根据日期查询预约设置信息-->
<select id="findByOrderDate" parameterType="date" resultType="com.oldlu.pojo.OrderSetting">
    select *
    from t_ordersetting
    where orderDate = #{orderdate}
</select>
<!--更新已预约人数-->
<update id="editReservationsByOrderDate" parameterType="com.oldlu.pojo.OrderSetting">
    update t_ordersetting set reservations = #{reservations} where orderDate = #{orderDate}
</update>

MemberDao.xml

<?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.oldlu.dao.MemberDao" >
    <select id="findAll" resultType="com.oldlu.pojo.Member">
        select * from t_member
    </select>
    <!--根据条件查询-->
    <select id="selectByCondition" parameterType="string" resultType="com.oldlu.pojo.Member">
        select * from t_member
        <if test="value != null and value.length > 0">
            where fileNumber = #{value} or phoneNumber = #{value} or name = #{value}
        </if>
    </select>
    <!--新增会员-->
    <insert id="add" parameterType="com.oldlu.pojo.Member">
        <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into t_member(fileNumber,name,sex,idCard,phoneNumber,regTime,password,email,birthday,remark)
        values (#{fileNumber},#{name},#{sex},#{idCard},#{phoneNumber},#{regTime},#{password},#{email},#{birthday},#{remark})
    </insert>
    <!--删除会员-->
    <delete id="deleteById" parameterType="int">
        delete from t_member where id = #{id}
    </delete>
    <!--根据id查询会员-->
    <select id="findById" parameterType="int" resultType="com.oldlu.pojo.Member">
        select * from t_member where id = #{id}
    </select>
    <!--根据id查询会员-->
    <select id="findByTelephone" parameterType="string" resultType="com.oldlu.pojo.Member">
        select * from t_member where phoneNumber = #{phoneNumber}
    </select>
    <!--编辑会员-->
    <update id="edit" parameterType="com.oldlu.pojo.Member">
        update t_member
        <set>
            <if test="fileNumber != null">
                fileNumber = #{fileNumber},
            </if>
            <if test="name != null">
                name = #{name},
            </if>
            <if test="sex != null">
                sex = #{sex},
            </if>
            <if test="idCard != null">
                idCard = #{idCard},
            </if>
            <if test="phoneNumber != null">
                phoneNumber = #{phoneNumber},
            </if>
            <if test="regTime != null">
                regTime = #{regTime},
            </if>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="email != null">
                email = #{email},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="remark != null">
                remark = #{remark},
            </if>
        </set>
        where id = #{id}
    </update>
    <!--根据日期统计会员数,统计指定日期之前的会员数-->
    <select id="findMemberCountBeforeDate" parameterType="string" resultType="int">
        select count(id) from t_member where regTime &lt;= #{value}
    </select>
    <!--根据日期统计会员数-->
    <select id="findMemberCountByDate" parameterType="string" resultType="int">
        select count(id) from t_member where regTime = #{value}
    </select>
    <!--根据日期统计会员数,统计指定日期之后的会员数-->
    <select id="findMemberCountAfterDate" parameterType="string" resultType="int">
        select count(id) from t_member where regTime &gt;= #{value}
    </select>
    <!--总会员数-->
    <select id="findMemberTotalCount" resultType="int">
        select count(id) from t_member
    </select>
</mapper>

OrderDao.xml

<?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.oldlu.dao.OrderDao">
    <resultMap id="baseResultMap" type="com.oldlu.pojo.Order">
        <id column="id" property="id"/>
        <result column="member_id" property="memberId"/>
        <result column="orderDate" property="orderDate"/>
        <result column="orderType" property="orderType"/>
        <result column="orderStatus" property="orderStatus"/>
        <result column="setmeal_id" property="setmealId"/>
    </resultMap>
    <!--新增-->
    <insert id="add" parameterType="com.oldlu.pojo.Order">
        <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into t_order(member_id,orderDate,orderType,orderStatus,setmeal_id)
        values (#{memberId},#{orderDate},#{orderType},#{orderStatus},#{setmealId})
    </insert>
    <!--动态条件查询-->
    <select id="findByCondition" parameterType="com.oldlu.pojo.Order" resultMap="baseResultMap">
        select * from t_order
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="memberId != null">
                and member_id = #{memberId}
            </if>
            <if test="orderDate != null">
                and orderDate = #{orderDate}
            </if>
            <if test="orderType != null">
                and orderType = #{orderType}
            </if>
            <if test="orderStatus != null">
                and orderStatus = #{orderStatus}
            </if>
            <if test="setmealId != null">
                and setmeal_id = #{setmealId}
            </if>
        </where>
    </select>
    <!--根据预约id查询预约信息,包括体检人信息、套餐信息-->
    <select id="findById4Detail" parameterType="int" resultType="map">
        select
            m.name      member,
            s.name      setmeal,
            o.orderDate orderDate,
            o.orderType orderType
        from
            t_order o,
            t_member m,
            t_setmeal s
        where o.member_id = m.id and o.setmeal_id = s.id and o.id = #{id}
    </select>
    <!--根据日期统计预约数-->
    <select id="findOrderCountByDate" parameterType="string" resultType="int">
        select count(id)
        from t_order
        where orderDate = #{value}
    </select>
    <!--根据日期统计预约数,统计指定日期之后的预约数-->
    <select id="findOrderCountAfterDate" parameterType="string" resultType="int">
        select count(id)
        from t_order
        where orderDate &gt;= #{value}
    </select>
    <!--根据日期统计到诊数-->
    <select id="findVisitsCountByDate" parameterType="string" resultType="int">
        select count(id)
        from t_order
        where orderDate = #{value} and orderStatus = '已到诊'
    </select>
    <!--根据日期统计到诊数,统计指定日期之后的到诊数-->
    <select id="findVisitsCountAfterDate" parameterType="string" resultType="int">
        select count(id)
        from t_order
        where orderDate &gt;= #{value} and orderStatus = '已到诊'
    </select>
    <!--热门套餐,查询前5条-->
    <select id="findHotSetmeal" resultType="map">
        select
            s.name,
            count(o.id)                  setmeal_count,
            count(o.id) / (select count(id)
                           from t_order) proportion
        from t_order o inner join t_setmeal s on s.id = o.setmeal_id
        group by o.setmeal_id
        order by setmeal_count desc
        limit 0, 4
    </select>
    <select id="findById" parameterType="int" resultType="com.oldlu.pojo.Order">
        select *
        from t_order
        where id = #{id}
    </select>
</mapper>

3. 预约成功页面展示

前面已经完成了体检预约,预约成功后页面会跳转到成功提示页面

orderSuccess.html)并展示预约的相关信息(体检人、体检套餐、体检时间等)。

3.1 页面调整

提供orderSuccess.html页面,展示预约成功后相关信息

<div class="info-title">
    <span class="name">体检预约成功</span>
</div>
<div class="notice-item">
    <div class="item-title">预约信息</div>
    <div class="item-content">
        <p>体检人:{{orderInfo.member}}</p>
        <p>体检套餐:{{orderInfo.setmeal}}</p>
        <p>体检日期:{{orderInfo.orderDate}}</p>
        <p>预约类型:{{orderInfo.orderType}}</p>
    </div>
</div>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            orderInfo: {}
        },
        mounted() {
            //发送ajax请求,根据预约ID查询相关信息,用于页面显示
            axios.post("/order/findById.do?id=" + id).then((response) => {
                if (response.data.flag) {
                    this.orderInfo = response.data.data;
                } else {
                    this.$message.error(response.data.message)
                }
            });
        }
    });
</script>

3.2 后台代码

3.2.1 Controller

在OrderController中提供findById方法,根据预约id查询预约相关信息

 /**
  * 根据id查询预约详细信息,包括套餐信息和会员信息
  * @param id
  * @return
  */
 @RequestMapping("/findById")
 public Result findById(Integer id) {
     try {
         Map map = orderService.findById(id);
         return new Result(true, MessageConstant.QUERY_ORDER_SUCCESS, map);
     } catch (Exception e) {
         e.printStackTrace();
         return new Result(false, MessageConstant.QUERY_ORDER_FAIL);
     }
 }

3.2.2 服务接口

在OrderService服务接口中扩展findById方法

//根据id查询预约信息,包括体检人信息、套餐信息
public Map findById(Integer id) throws Exception;
123

3.2.3 服务实现类

在OrderServiceImpl服务实现类中实现findById方法

/**
 * 根据预约ID查询预约详细信息,包括体检人信息、套餐信息
 *
 * @param id
 * @return
 * @throws Exception
 */
@Override
public Map findById(Integer id) throws Exception {
    Map map = orderDao.findById4Detail(id);
    //处理日期格式
    if (map != null) {
        Date orderDate = (Date) map.get("orderDate");
        map.put("orderDate", DateUtils.parseDate2String(orderDate));
    }
    return map;
}

3.2.4 Dao接口

在OrderDao接口中扩展findById4Detail方法

public Map findById4Detail(Integer id);

3.2.5 Mapper映射文件

在OrderDao.xml映射文件中提供SQL语句


<!‐‐根据预约id查询预约信息,包括体检人信息、套餐信息‐‐>
<!--根据预约id查询预约信息,包括体检人信息、套餐信息-->
<select id="findById4Detail" parameterType="int" resultType="map">
    select
        m.name      member,
        s.name      setmeal,
        o.orderDate orderDate,
        o.orderType orderType
    from
        t_order o,
        t_member m,
        t_setmeal s
    where o.member_id = m.id and o.setmeal_id = s.id and o.id = #{id}
</select>
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
4月前
|
存储 运维 BI
云HIS综合管理系统源码,门诊预约挂号、收费结算、排班、医护协同、药房、药库、电子病历等功能模块
_HIS系统摘要:_ HIS是医院信息管理系统,涵盖门诊、住院、药房、药库管理等,支持财务、病人及物资信息处理。门诊医生工作站具备友好的交互,与多系统接口集成。功能包括医生就诊、查询、住院预约、数据设置及用户管理。云HIS采用SaaS模式,适合基层医疗机构,提供综合管理和业务支持,确保运营监管并易于扩展。系统展示包括业务首页、综合管理系统、费用统计和出院结算界面。
109 8
云HIS综合管理系统源码,门诊预约挂号、收费结算、排班、医护协同、药房、药库、电子病历等功能模块
|
4月前
|
SQL 数据库连接 数据库
医院网络预约系统咨询预约登记OA系统
医院网络预约系统咨询预约登记OA系统
62 2
|
6月前
|
安全 Java 关系型数据库
医院门诊管理系统的设计与实现
医院门诊管理系统的设计与实现
78 1
|
6月前
|
小程序 JavaScript Java
医院挂号预约|医院挂号预约小程序|基于微信小程序的医院挂号预约系统设计与实现(源码+数据库+文档)
医院挂号预约|医院挂号预约小程序|基于微信小程序的医院挂号预约系统设计与实现(源码+数据库+文档)
228 0
|
6月前
|
数据挖掘 C# 开发工具
医院体检信息系统
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
72 1
医院体检信息系统
|
6月前
|
C#
C#掌上医院预约挂号支付系统源码
医院微信预约挂号系统是一种基于微信平台的医疗服务系统,它利用微信的广泛覆盖和便捷性,为患者提供线上预约挂号的服务。通过该系统,患者可以使用自己的微信账号登录,浏览医院的医生排班信息,选择合适的医生和就诊时间进行预约。 医院微信预约挂号系统主要是让自费、医保患者在手机上就能实现就医全过程,实时自费、医保结算,同时还可以查询检查检验报告等就诊信息。
41 3
|
6月前
|
小程序 安全 搜索推荐
​ C#掌上医院预约挂号系统源码 一套成熟的医院/诊所预约挂号小程序需要了解哪些方面?
"互联网+医院"服务水平不断的提升,各类门诊部、中医馆、诊所、乡镇卫生院、社区卫生服务中心等医疗机构服务形式开始拓展互联网线上渠道。利用微信小程序、公众号(服务号)+网页端等形式进行开发,其中,预约小程序,门诊预约挂号系统的稳定性强、运行维护方便、是被众多医院机构信任与选择的。
97 1
|
6月前
|
小程序
智慧医院预约挂号平台源码,可直接线上预约挂号、快捷缴费,查看报告
医院线上预约挂号平台既可以让患者足不出户就可以利用微信进行在线挂号,实现分时段就诊,就诊后也可以直接使用手机微信缴费,还可以通过微信实现查询费用明细及药品清单,检查、检验报告,住院服务等功能。
137 1
智慧医院预约挂号平台源码,可直接线上预约挂号、快捷缴费,查看报告
|
6月前
|
存储 安全 前端开发
医院住院综合服务管理系统
医院住院综合服务管理系统
|
6月前
|
监控 小程序 数据可视化
HIS预约挂号系统源码 看病挂号快人一步
技术架构:uni-app+.net+SqlServer 2012+微信公众号、支付宝小程序。
91 2