700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 健康管理系统第七天(移动端_体检预约(手机号校验 发送验证码之后30秒倒计时效果 生

健康管理系统第七天(移动端_体检预约(手机号校验 发送验证码之后30秒倒计时效果 生

时间:2020-02-13 18:33:43

相关推荐

健康管理系统第七天(移动端_体检预约(手机号校验 发送验证码之后30秒倒计时效果 生

一、体检预约流程

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

1、在移动端首页点击体检预约,页面跳转到套餐列表页面

2、在套餐列表页面点击要预约的套餐,页面跳转到套餐详情页面

3、在套餐详情页面点击立即预约,页面跳转到预约页面

4、在预约页面录入体检人信息,包括手机号,点击发送验证码

5、在预约页面录入收到的手机短信验证码,点击提交预约,完成体检预约

1.手机号校验2.发送验证码之后30秒倒计时效果3.调用ValidateCodeUtils生成四位数字验证码4.调用SMSUtils向指定手机发送验证码

二、体检预约

1.在移动端的orderInfo.html根据套餐id获取套餐基本信息

1.1 前端执行流程

1.2 后端执行逻辑:后端就是根据接收的id从数据库中查找出对应的套餐信息返回给前端

2.手机号校验

2.1 第一步:在页面导入的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;}}

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

3.发送验证码之后30秒倒计时效果

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

4.发送ajax请求

5.后台请求之后调用ValidateCodeUtils生成四位数字验证码,调用SMSUtils向指定手机发送验证码

package com.oracle.utils;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.dysmsapi.model.v0525.SendSmsRequest;import com.aliyuncs.dysmsapi.model.v0525.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_193233375";//发送短信验证码public static final String ORDER_NOTICE = "SMS_193515443";//体检预约成功通知/*** 发送短信* @param phoneNumbers* @param param* @throws ClientException*/public static void sendShortMessage(String templateCode,String phoneNumbers,String param) throws ClientException {// 设置超时时间-可自行调整System.setProperty(".client.defaultConnectTimeout", "10000");System.setProperty(".client.defaultReadTimeout", "10000");// 初始化ascClient需要的几个参数final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)final String domain = "";// 短信API产品域名(接口地址固定,无需修改)// 替换成你的AKfinal String accessKeyId = "LTAI5GEC5ULqFHxSsxXUPS4P";// 你的accessKeyId,参考本文档步骤2final String accessKeySecret = "QxCqQM6TXXyjv8ZbIEC4NgCDkMPdID";// 你的accessKeySecret,参考本文档步骤2// 初始化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("FlyHigh健康管理云");// 必填:短信模板-可在短信控制台中找到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("请求成功");}}}

package com.oracle.utils;import java.util.Random;/*** 随机生成验证码工具类*/public class ValidateCodeUtils {/*** 随机生成验证码* @param length 长度为4位或者6位* @return*/public static Integer generateValidateCode(int length){Integer code =null;if(length == 4){code = new Random().nextInt(9999);//生成随机数,最大为9999if(code < 1000){code = code + 1000;//保证随机数为4位数字}}else if(length == 6){code = new Random().nextInt(999999);//生成随机数,最大为999999if(code < 100000){code = code + 100000;//保证随机数为6位数字}}else{throw new RuntimeException("只能生成4位或6位数字验证码");}return code;}/*** 随机生成指定长度字符串验证码* @param length 长度* @return*/public static String generateValidateCode4String(int length){Random rdm = new Random();String hash1 = Integer.toHexString(rdm.nextInt());String capstr = hash1.substring(0, length);return capstr;}}

package com.oracle.controller;import com.aliyuncs.exceptions.ClientException;import com.oracle.constant.MessageConstant;import com.oracle.constant.RedisConstant;import com.oracle.entity.Result;import com.oracle.utils.SMSUtils;import com.oracle.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;@RestController@RequestMapping("/validateCode")public class ValidateCodeController {@AutowiredJedisPool jedisPool;/*** 提供方法发送短信验证码,并将验证码保存到redis中*/@RequestMapping("/send4ValidateCode")public Result getAllSetmeal(String telephone){//生成四位数的验证码Integer validateCode = ValidateCodeUtils.generateValidateCode(4);//发送手机验证码至指定的手机try {SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone,validateCode.toString());} catch (ClientException e) {e.printStackTrace();//发送验证码失败return new Result(false,MessageConstant.SEND_VALIDATECODE_FAIL);}//在控制台打印验证码System.out.println(validateCode);//将手机验证码保存至redis中,5分钟后过期jedisPool.getResource().setex(telephone+ RedisConstant.SENDTYPE_ORDER,5*60,validateCode.toString());return new Result(true,MessageConstant.SEND_VALIDATECODE_SUCCESS);}}

6.日历展示

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

7.提交预约请求

7.1 前台提交预约

7.2 后台接收请求之后的处理过程

package com.oracle.controller;import com.alibaba.dubbo.config.annotation.Reference;import com.aliyuncs.exceptions.ClientException;import com.oracle.constant.MessageConstant;import com.oracle.constant.RedisConstant;import com.oracle.constant.RedisMessageConstant;import com.oracle.entity.Result;import com.oracle.pojo.Order;import com.oracle.service.OrderService;import com.oracle.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.JedisPool;import java.util.Map;@RestController@RequestMapping("/order")public class OrderController {@ReferenceOrderService orderService;@AutowiredJedisPool jedisPool;/*** 由于实体类中没有一个叫OrderInfo的实体类,所以采用map接收数据* 提交用户的预约信息* @return Result*/@RequestMapping("/submit")public Result submitOrder(@RequestBody Map map){//获取用户的手机号码String telephone = (String) map.get("telephone");//从redis里面取出发送的验证码String codeInRedis = jedisPool.getResource().get(telephone + RedisMessageConstant.SENDTYPE_ORDER);//获取用户输入的验证码String validateCode = (String)map.get("validateCode");//校验用户输入的验证码是否等于redis中保存的验证码if(codeInRedis==null||!codeInRedis.equalsIgnoreCase(validateCode)){//如果redis中的验证码过期了,如果用户输入的验证码和redis中的验证码不一致return new Result(false, MessageConstant.VALIDATECODE_ERROR);}//如果验证码输入正确,则调用体检预约的服务Result result=null;try {map.put("orderType", Order.ORDERTYPE_WEIXIN);result = orderService.addOrder(map);} catch (Exception e) {e.printStackTrace();}//预约成功 发送短信通知if(result.isFlag()){String orderDate = (String) map.get("orderDate");try {//发送用户的预约日期至用户手机SMSUtils.sendShortMessage(SMSUtils.ORDER_NOTICE,telephone,orderDate);} catch (ClientException e) {e.printStackTrace();}}return result;}/*** 根据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);}}}

7.3 完善OrderService

package com.oracle.service;import com.oracle.entity.Result;import java.util.Map;public interface OrderService {//添加体检预约Result addOrder(Map map);//通过orderID查找Order信息、Setmeal信息等Map findById(Integer id);}

7.4 体检预约方法处理逻辑比较复杂,业务流程如下所示

在health_service_provider工程中创建体检预约服务实现类OrderServiceImpl并实现体检预约方法。 体检预约方法处理逻辑比较复杂,需要进行如下业务处理: 1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约 2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约3、检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约,则无法完成再次预约 4、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约 5、预约成功,更新当日的已预约人数,实现代码如下:

package com.oracle.service;import com.alibaba.dubbo.config.annotation.Service;import com.oracle.constant.MessageConstant;import com.oracle.dao.MemberDao;import com.oracle.dao.OrderDao;import com.oracle.dao.OrderSettingDao;import com.oracle.entity.Result;import com.oracle.pojo.Member;import com.oracle.pojo.Order;import com.oracle.pojo.OrderSetting;import com.oracle.utils.DateUtils;import org.springframework.beans.factory.annotation.Autowired;import java.util.Date;import java.util.Map;@Service(interfaceClass = OrderService.class)public class OrderServiceImpl implements OrderService{@AutowiredOrderDao orderDao;@AutowiredOrderSettingDao orderSettingDao;@AutowiredMemberDao memberDao;/*** 体检预约方法处理逻辑比较复杂,需要进行如下业务处理:* 1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约* 2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约* 3、检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约 则无法完成再次预约* 4、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约* 5、预约成功,更新当日的已预约人数* @param map* @return*/@Overridepublic Result addOrder(Map map) {//1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约String orderDate = (String) map.get("orderDate");//将字符串类型的日期类转换成Date类型Date date = DateUtils.parseString2Date(orderDate);//根据预约日期查询t_ordersetting表是否存在对应的日期,如果存在才可以预约,如果不存在就不能预约OrderSetting orderSetting = orderSettingDao.findByOrderDate(date);if(orderSetting==null){//预约日期不存在,不能预约return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);}//如果预约日期存在,那么接着判断预约日期是否满员int number = orderSetting.getNumber(); //可预约人数int reservations = orderSetting.getReservations(); //已预约人数if(number==reservations){//预约人数已满,不能进行预约return new Result(false,MessageConstant.ORDER_FULL);}//如果预约日期没有满员,可以进行预约,那么这时会判断该用户是否是会员//根据手机号码判断该用户是否是会员String telephone = (String) map.get("telephone");Member member = memberDao.findByTelephone(telephone);//如果存在该会员,那么为了防止重复预约 需要查询对应会员是否已经预约if(member!=null){Integer memberId = member.getId();//会员IDInteger setmealId = Integer.valueOf((String) map.get("setmealId")); //套餐IDOrder order = new Order(memberId,date,null,null,setmealId);Integer orderDaoByCondition = orderDao.findByCondition(order);if(orderDaoByCondition>0){//该会员已经当天预约过,不能再次预约return new Result(false,MessageConstant.HAS_ORDERED);}}//用户可以进行预约,设置预约人数+1orderSetting.setReservations(orderSetting.getReservations()+1);//更新已预约人数orderSettingDao.upateOrderSetting(orderSetting);//如果该用户不是会员,需要添加到会员列表if(member==null){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.addMember(member);}//将预约信息保存到预约表里面Order order = new Order(member.getId(),date,(String)map.get("orderType"),Order.ORDERSTATUS_NO,Integer.parseInt((String)map.get("setmealId")));orderDao.addOrder(order);return new Result(true,MessageConstant.ORDER_SUCCESS,order.getId());}@Overridepublic Map findById(Integer id) {Map map = orderDao.findDetailsById(id);System.out.println("MAP:"+map);if(map!=null){Date orderDate = (Date)map.get("orderDate");//由于从数据库中查找出来的类型是date类型,但是在前台页面展示的是String类型的,所以需要进行转换map.put("orderDate",DateUtils.parseDate2String(orderDate));}return map;}}

7.5 Dao接口

OrderDao

package com.oracle.dao;import com.oracle.pojo.Order;import com.oracle.pojo.OrderSetting;import org.springframework.stereotype.Repository;import java.util.Date;import java.util.List;import java.util.Map;@Repositorypublic interface OrderDao {//根据前台传过来的体检预约信息在订单表中判断是否存在Integer findByCondition(Order order);//添加预约信息到预约表里面void addOrder(Order order);}

OrderSettingDao

package com.oracle.dao;import com.oracle.pojo.OrderSetting;import org.springframework.stereotype.Repository;import java.util.Date;import java.util.List;import java.util.Map;@Repositorypublic interface OrderSettingDao {//提交体检预约的时候根据date判断该日期是否存在OrderSetting findByOrderDate(Date date);//更新已预约人数void upateOrderSetting(OrderSetting orderSetting);}

memberDao

package com.oracle.dao;import com.oracle.pojo.Member;import org.springframework.stereotype.Repository;@Repositorypublic interface MemberDao {//根据用户手机号码判断用户是否为会员Member findByTelephone(String telephone);//添加用户void addMember(Member member);}

7.6 Mapper映射文件

OrderSettingDao.xml

<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.oracle.dao.OrderSettingDao"><!--提交体检预约时判断该日期是否存在预约--><select id="findByOrderDate" parameterType="Date" resultType="com.oracle.pojo.OrderSetting">select * from t_ordersetting where orderDate = #{orderDate}</select><!--更新已预约人数--><update id="upateOrderSetting" parameterType="com.oracle.pojo.OrderSetting">UPDATE t_ordersetting SET reservations=#{reservations} where orderDate=#{orderDate}</update></mapper>

OrderDao.xml

<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.oracle.dao.OrderDao"><!--判断该用户会员是否当天已经进行了预约--><select id="findByCondition" parameterType="com.oracle.pojo.Order" resultType="java.lang.Integer">select count(*) from t_order<where><if test="memberId != null">and member_id = #{memberId}</if><if test="orderDate != null">and orderDate = #{orderDate}</if><if test="setmealId != null">and setmeal_id = #{setmealId}</if></where></select><!--添加预约信息到预约表--><insert id="addOrder" parameterType="com.oracle.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></mapper>

memberDao.xml

<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.oracle.dao.MemberDao"><!--根据电话号码查询是否是会员--><select id="findByTelephone" parameterType="String" resultType="com.oracle.pojo.Member">select * from t_member where phoneNumber=#{phoneNumber};</select><!--添加用户--><insert id="addMember" parameterType="com.oracle.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></mapper>

八、预约成功页面展示

前面已经完成了体检预约,预约成功后页面会跳转到成功提示页面(orderSuccess.html)并展示预约的相关信息(体检人、体检套餐、体检时间等)。

8.1 完善OrderController

/*** 根据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);}}

8.2 OrderService服务接口

package com.oracle.service;import com.oracle.entity.Result;import java.util.Map;public interface OrderService {//通过orderID查找Order信息、Setmeal信息等Map findById(Integer id);}

8.3 OrderServiceImpl服务实现类

/*** 根据id查询预约信息,包括套餐信息和会员信息* @param id* @return*/@Overridepublic Map findById(Integer id) throws Exception{Map map = orderDao.findDetailsById(id);System.out.println("MAP:"+map);if(map!=null){Date orderDate = (Date)map.get("orderDate");map.put("orderDate",DateUtils.parseDate2String(orderDate));}return map;}

8.4 在OrderDao接口中扩展findDetailsById方法

public interface OrderDao {Map findDetailsById(Integer id);}

8.5 OrderDao.xml映射文件

<!--根据预约id查询对应的预约信息(预约信息 会员信息 套餐信息--><select id="findDetailsById" parameterType="int" resultType="map">select m.name member ,s.name setmeal,o.orderDate orderDate,o.orderType orderType fromt_order o,t_member m,t_setmeal swhere o.member_id=m.id and o.setmeal_id=s.id and o.id=#{id}</select>

9.启动测试

健康管理系统第七天(移动端_体检预约(手机号校验 发送验证码之后30秒倒计时效果 生成验证码 向手机发送验证码))

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。