package me.zhengjie.system.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.sql.Timestamp; /**
* @author jie
* @date 2018-12-26
*/
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "verification_code")
public class VerificationCode { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private String code; /**
* 使用场景,自己定义
*/
private String scenes; /**
* true 为有效,false 为无效,验证时状态+时间+具体的邮箱或者手机号
*/
private Boolean status = true; /**
* 类型 :phone 和 email
*/
@NotBlank
private String type; /**
* 具体的phone与email
*/
@NotBlank
private String value; /**
* 创建日期
*/
@CreationTimestamp
private Timestamp createTime; public VerificationCode(String code, String scenes, @NotBlank String type, @NotBlank String value) {
this.code = code;
this.scenes = scenes;
this.type = type;
this.value = value;
}
}
package me.zhengjie.system.rest;

import me.zhengjie.common.utils.ElAdminConstant;
import me.zhengjie.common.utils.RequestHolder;
import me.zhengjie.core.security.JwtUser;
import me.zhengjie.core.utils.JwtTokenUtil;
import me.zhengjie.system.domain.VerificationCode;
import me.zhengjie.system.service.VerificationCodeService;
import me.zhengjie.tools.domain.vo.EmailVo;
import me.zhengjie.tools.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*; /**
* @author jie
* @date 2018-12-26
*/
@RestController
@RequestMapping("api")
public class VerificationCodeController { @Autowired
private VerificationCodeService verificationCodeService; @Autowired
private JwtTokenUtil jwtTokenUtil; @Autowired
@Qualifier("jwtUserDetailsService")
private UserDetailsService userDetailsService; @Autowired
private EmailService emailService; @PostMapping(value = "/code/resetEmail")
public ResponseEntity resetEmail(@RequestBody VerificationCode code) throws Exception {
code.setScenes(ElAdminConstant.RESET_MAIL);
EmailVo emailVo = verificationCodeService.sendEmail(code);
emailService.send(emailVo,emailService.find());
return new ResponseEntity(HttpStatus.OK);
} @PostMapping(value = "/code/email/resetPass")
public ResponseEntity resetPass() throws Exception {
JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
VerificationCode code = new VerificationCode();
code.setType("email");
code.setValue(jwtUser.getEmail());
code.setScenes(ElAdminConstant.RESET_MAIL);
EmailVo emailVo = verificationCodeService.sendEmail(code);
emailService.send(emailVo,emailService.find());
return new ResponseEntity(HttpStatus.OK);
} @GetMapping(value = "/code/validated")
public ResponseEntity validated(VerificationCode code){
verificationCodeService.validated(code);
return new ResponseEntity(HttpStatus.OK);
}
}
package me.zhengjie.system.service;

import me.zhengjie.system.domain.VerificationCode;
import me.zhengjie.tools.domain.vo.EmailVo; /**
* @author jie
* @date 2018-12-26
*/
public interface VerificationCodeService { /**
* 发送邮件验证码
* @param code
*/
EmailVo sendEmail(VerificationCode code); /**
* 验证
* @param code
*/
void validated(VerificationCode code);
}
package me.zhengjie.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.common.utils.ElAdminConstant;
import me.zhengjie.system.domain.VerificationCode;
import me.zhengjie.system.repository.VerificationCodeRepository;
import me.zhengjie.system.service.VerificationCodeService;
import me.zhengjie.tools.domain.vo.EmailVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; /**
* @author jie
* @date 2018-12-26
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class VerificationCodeServiceImpl implements VerificationCodeService { @Autowired
private VerificationCodeRepository verificationCodeRepository; @Value("${code.expiration}")
private Integer expiration; @Override
@Transactional(rollbackFor = Exception.class)
public EmailVo sendEmail(VerificationCode code) {
EmailVo emailVo = null;
String content = "";
VerificationCode verificationCode = verificationCodeRepository.findByScenesAndTypeAndValueAndStatusIsTrue(code.getScenes(),code.getType(),code.getValue());
// 如果不存在有效的验证码,就创建一个新的
if(verificationCode == null){
code.setCode(RandomUtil.randomNumbers (6));
content = ElAdminConstant.EMAIL_CODE + code.getCode() + "</p>";
emailVo = new EmailVo(Arrays.asList(code.getValue()),"eladmin后台管理系统",content);
timedDestruction(verificationCodeRepository.save(code));
// 存在就再次发送原来的验证码
} else {
content = ElAdminConstant.EMAIL_CODE + verificationCode.getCode() + "</p>";
emailVo = new EmailVo(Arrays.asList(verificationCode.getValue()),"eladmin后台管理系统",content);
}
return emailVo;
} @Override
public void validated(VerificationCode code) {
VerificationCode verificationCode = verificationCodeRepository.findByScenesAndTypeAndValueAndStatusIsTrue(code.getScenes(),code.getType(),code.getValue());
if(verificationCode == null || !verificationCode.getCode().equals(code.getCode())){
throw new BadRequestException("无效验证码");
} else {
verificationCode.setStatus(false);
verificationCodeRepository.save(verificationCode);
}
} /**
* 定时任务,指定分钟后改变验证码状态
* @param verifyCode
*/
private void timedDestruction(VerificationCode verifyCode) {
//以下示例为程序调用结束继续运行
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
try {
executorService.schedule(() -> {
verifyCode.setStatus(false);
verificationCodeRepository.save(verifyCode);
}, expiration * 60 * 1000L, TimeUnit.MILLISECONDS);
}catch (Exception e){
e.printStackTrace();
}
}
}
package me.zhengjie.system.repository;

import me.zhengjie.system.domain.VerificationCode;
import org.springframework.data.jpa.repository.JpaRepository; /**
* @author jie
* @date 2018-12-26
*/
public interface VerificationCodeRepository extends JpaRepository<VerificationCode, Long> { /**
* 获取有效的验证码
* @param scenes 业务场景,如重置密码,重置邮箱等等
* @param type
* @param value
* @return
*/
VerificationCode findByScenesAndTypeAndValueAndStatusIsTrue(String scenes,String type,String value);
}

VerificationCodeService的更多相关文章

随机推荐

  1. PTA 天梯赛 L1

    L1-002 打印沙漏 细节:就是在  (i>j&&i+j<r+1) 这个区间里才有空格,然后就是 for 循环   for(r=1; ;r+=2)  条件不满足之后还会再 ...

  2. 递归(VBA实现)

    案列: 给定n个数,取任意g个数之和等于h的组合. 采用递归的方式实现: Option Explicit Dim arr1(1 To 10000, 1 To 1) As String Dim k, g ...

  3. 2020牛客寒假算法基础集训营5 G街机争霸

    题目描述 哎,又是银首,要是你这个签到题少WA一发就金了 牛牛战队的队员打完比赛以后又到了日常甩锅的时间.他们心情悲伤,吃完晚饭以后,大家相约到一个街机厅去solo.牛牛和牛能进入了一个迷宫,这个迷宫 ...

  4. 对比Node.js和Python 帮你确定理想编程解决方案!

    世上没有最好的编程语言.有些编程语言比其他编程语言用于更具体的事情.比如,你可能需要移动应用程序,网络应用程序或更专业化的系统,则可能会有特定的语言.但是我们暂时假设你需要的是一个相对来说比较简单的网 ...

  5. python编程:从入门到实践----第六章>字典

    一.一个简单的字典:alien_0存储外星人的颜色和点数,使用print打印出来 alien_0 = {'color': 'green','points': 5} print(alien_0['col ...

  6. JDBC-使用Java连接数据库-基础篇

    这是小主第一次写Java连接数据库博客,初学Java之时,Java连接数据库是我最头疼的,不过经过一个月的学习,也差不多略有收获,所以给大家分享一下. Java连接数据库大约需要五大步骤: 创建数据库 ...

  7. 计蒜客 蒜头君回家(有条件的BFS)

    蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家.花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方.” 蒜头君希望能尽快回到家中,他需要首先取得任意 ...

  8. LeetCode——456.132模式

    给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当 ...

  9. WebAPI异常捕捉处理,结合log4net日志(webapi框架)

    一:异常捕捉处理 首先,在我们需要区分controller的类型.是全部基层controller,还是Apicontroller.(当然一般API框架,用的都是Apicontroller).两者异常处 ...

  10. sourceTree 代码回滚(git 和http)

    近些时候,有遇到提交后代码有误的情况,所以需要回退到前一个版本.因为不常见,所以每次都不是很熟练,记录于此,以备查阅. 一.[将master重置到这次提交] 在sourceTree中选中错误的提交的下 ...