1.验证码补全
//发送验证码
sendValidateCode() {
/**
* 1.手机号不能为空
* 2.手机号符合规范
* 3.发送一分钟后才可再次发送
*/
//获取手机号
let telephone = this.orderInfo.telephone;
//验证手机号不能空
if (telephone == undefined){
this.$message.error("请输入手机号");
return null;
}
//验证手机号格式正确
//第一位为1,第二位为3-9,第三位往后九位都为0-9
let ref=/^1[3-9][0-9]{9}$/
if(!ref.test(telephone)){
this.$message.error("手机号格式错误!")
return null;
}
let number = 10;//倒计时的变量
let btn = $("#validateCodeButton");
let id = setInterval(function (){
//屏蔽按钮,在按钮显示时间的倒计时
number --;
//jQuery设置标签的属性
btn.attr("disabled",true);
//修改按钮上的文字
btn.val(number+"秒后重新发送");
if (number == 0){
//终止定时器,按钮还原
btn.val("发送验证码");
btn.attr("disabled",false);
//清空定时器的执行 传递参数id值
clearInterval(id)
}
},1000);
axios.get("/SetMealController/sendCode.do?telephone="+telephone).then(response=>{
if (response.data.flag){
this.code=response.data.data
console.log(response.data.data)
}
})
},
发送验证码需要验证手机号格式是否正确,使用正则表达式
let ref=/^1[3-9][0-9]{9}$/
实现手机号规则判断
并实现了验证码隔时发送,使用JS的
setInterval
计时器,循环减少设置的倒计时,并在期间屏蔽发送按钮
btn.attr("disabled",true);
通过更改其"disabled"属性的值实现;
使用JQuery的ID选择器
let btn = $("#validateCodeButton");
实现对按钮的选择
后端如下:
/**
* 接收手机号,发送验证码
* @param telephone
* @return
* 调用工具类发送验证码
* 产生4位随机数
* 发送成功,在Redis中存储一份验证码,设置5分钟过期(校验验证是否正确)
*/
@GetMapping("/sendCode")
public Result sendCode(String telephone){
Integer capstr= ValidateCodeUtils.generateValidateCode(4);
try {
SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone, String.valueOf(capstr));
Jedis jedis=jedisPool.getResource();
jedis.setex(telephone+ RedisConstant.SENDTYPE_ORDER,60*5,capstr+"");
jedis.close();
return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);
} catch (ClientException e) {
e.printStackTrace();
return new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);
}
}
}
通过telephone拼接键,作为Key,将Redis中的键值对做对比,返回正确的信息;
2.预约套餐逻辑实现
1.前端验证表单数据的完整和正确性
//提交预约
submitOrder(){
/**
* 校验表单数据
* 1.姓名不能为空且大于一个字符
* 2.手机号不能为空且符合规范
* 3.身份证位数合适且符合规范
* 4.验证码不能为空
*/
if (this.orderInfo.name===undefined){
this.$message.error("请填写姓名");
return ;
}
if (this.orderInfo.name.length<2){
this.$message.error("姓名不能少于2个字");
return ;
}
// let reg = /^[\u4E00-\u9FA5]+$/;
// if (!reg.test(name)){
// this.$message.error("姓名必须是汉字");
// return ;
// }
//手机号和验证码,写了就行
let telephone = this.orderInfo.telephone;
if (telephone == undefined){
this.$message.error("请输入手机号");
return ;
}
reg = /^1[3-9][0-9]{9}$/;
//正则表达式方法,test(被检测字符串),正则匹配成功返回true
if( ! reg.test(telephone)){
this.$message.error("手机号格式错误");
return ;
}
if (this.orderInfo.validateCode == undefined){
this.$message.error("请填写验证码");
return ;
}
let idCard = this.orderInfo.idCard;
if (idCard == undefined){
this.$message.error("请填写身份证号");
return ;
}
//验证身份证号
reg=/^[1-6][0-9]{16}[0-9X]$/
if (!reg.test(idCard)){
this.$message.error("身份证号格式错误");
return ;
}
//验证预约日期,JS的日历,用户只能选择,不能修改
if (this.orderInfo.orderDate == undefined){
this.$message.error("请选择预约日期");
return ;
}
axios.post("/OrderController/submitOrder.do",this.orderInfo).then(res=>{
if (res.data.flag){
this.$message.success(res.data.message);
location.href="orderSuccess.html"
}else {
this.$message.error(res.data.message);
}}
)
},
复杂判断基本使用正则表达式,大X为身份证的10,拼接到9后
2.后端逻辑实现代码:
/**
* {"setmealId":"13","sex":"1","name":"石松","telephone":"13800138000",
* "validateCode":"1234","idCard":"123456789012345678","orderDate":"2024-10-25"}
* 保存预约数据
* 体检预约方法处理逻辑比较复杂,需要进行如下业务处理:
*
* 1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约 t_ordersetting
*
* 2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约 t_ordersetting
*
* 3、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约 t_member
* 4、检查用户是否重复预约(同一个用户在同一天预约了同一个套餐),如果是重复预约则无法完成再次预约 t_order
*
* 5、预约成功,更新当日的已预约人数 t_ordersetting
*/
1、检查用户所选择的预约日期是否已经提前进行了预约设置,如果没有设置则无法进行预约 t_ordersetting
OrderSetting orderSetting =orderSettingMapper.queryOrderSettingByOrderDate(map.get("orderDate"));
<select id="queryOrderSettingByOrderDate" parameterType="String" resultType="orderSetting">
select id,orderDate,number,reservations from t_ordersetting
where orderDate = #{orderDate}
</select>
//预约日期查询结果是 null
if(orderSetting == null){
return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
}
//2、检查用户所选择的预约日期是否已经约满,如果已经约满则无法预约 t_ordersetting
//orderSetting对象中的 number值大于reservations值,就可以预约
if (orderSetting.getReservations() >= orderSetting.getNumber()) {
return new Result(false, MessageConstant.ORDER_FULL);
}
预设为空则不能预约
预设的预约值大于等于全部值,预约已满
2、检查当前用户是否为会员,如果是会员则直接完成预约,如果不是会员则自动完成注册并进行预约 t_member
Member member =memberMapper.ifMember(map.get("telephone"));
if (member!=null){//是会员,查看是否约过
try {
Order order = new Order();
order.setSetmealId(Integer.parseInt(map.get("setmealId")));//存储套餐ID
order.setOrderDate(Date2Utils.parseString2Date(map.get("orderDate")));//存储预约的日期
order.setMemberId(member.getId());//存储用户的ID
int count = orderMapper.queryOrderByMember(order);
if (count!=0){
return new Result(false,MessageConstant.HAS_ORDERED);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
if (member==null){//不是会员,肯定没约过,直接帮他注册帮他约
//mapper成注册会员
member=new Member();
member.setName(map.get("name"));
member.setSex(map.get("sex"));
member.setIdCard(map.get("idCard"));
member.setPhoneNumber(map.get("telephone"));
member.setRegTime(new Date());
//mapper层,会员的数据写入到会员表
memberMapper.addMember(member);
}
若是会员,则查看会员当天是否约过此类型的套餐,SQL语句
@Select("select count(0) from t_order " +
"where member_id = #{memberId} " +
"and orderDate=#{orderDate} " +
"and setmeal_id = #{setmealId} ")
int queryOrderByMember(Order order);
需要会员id,当天日期和套餐id
若不是会员,则直接注册会员
if (member==null){//不是会员,肯定没约过,直接帮他注册帮他约
//mapper成注册会员
member=new Member();
member.setName(map.get("name"));
member.setSex(map.get("sex"));
member.setIdCard(map.get("idCard"));
member.setPhoneNumber(map.get("telephone"));
member.setRegTime(new Date());
//mapper层,会员的数据写入到会员表
memberMapper.addMember(member);
}
3、预约成功,更新当日的已预约人数 t_ordersetting
orderSettingMapper.updatareservations(map.get("orderDate"));
Order order = new Order();
try {
order.setOrderDate(Date2Utils.parseString2Date(map.get("orderDate")));//设置预约日期
order.setSetmealId(Integer.parseInt(map.get("setmealId")));//设置套餐ID
order.setOrderStatus(Order.ORDERSTATUS_NO);
order.setOrderType(Order.ORDERTYPE_WEIXIN);
//设置会员的Id
order.setMemberId(member.getId());
orderMapper.addOrder(order);
return new Result(true,MessageConstant.ORDER_SUCCESS,order.getId());
} catch (Exception e) {
throw new RuntimeException(e);
}
补上其他大佬发现的问题及解决办法