-
项目背景
领导说要实现一个二维码过期功能,只要用这个二维码消费(进入闸机后),这个二维码就不能用 -
项目解决需求思路
-
笨方法
为了实现只能使用一次就过期,可以在生成二维码时,在二维码中加入一个随机字符串作为token,并将这个token与二维码对应的状态保存在数据库中,初始状态为未使用。当用户扫码时,首先根据二维码中的token在数据库中查找对应的状态,如果为未使用,则表示该二维码还未被使用过,可以继续使用,并将状态更新为已使用;如果为已使用,则表示该二维码已经被使用过,不能再次使用。
以下是一个示例代码,假设已经有一个 QrCode 实体类表示二维码信息,并且使用了 Spring 框架:
@RestController
@RequestMapping("/qr-code")
public class QrCodeController {
@Autowired
private QrCodeRepository qrCodeRepository;
// 生成二维码并保存到数据库中
@PostMapping("/generate")
public QrCode generateQrCode() {
QrCode qrCode = new QrCode();
// 生成随机 token
String token = UUID.randomUUID().toString();
qrCode.setToken(token);
// 设置二维码图片
BufferedImage qrImage = generateQrImage(token);
qrCode.setQrImage(qrImage);
// 保存到数据库
qrCodeRepository.save(qrCode);
return qrCode;
}
// 扫码验证,检查二维码是否已经使用过
@GetMapping("/scan/{token}")
public ResponseEntity<String> scanQrCode(@PathVariable String token) {
QrCode qrCode = qrCodeRepository.findByToken(token);
if (qrCode == null) {
return ResponseEntity.notFound().build();
}
if (qrCode.isUsed()) {
return ResponseEntity.badRequest().body("该二维码已经使用过");
}
qrCode.setUsed(true);
qrCodeRepository.save(qrCode);
return ResponseEntity.ok("验证通过");
}
// 生成二维码图片
private BufferedImage generateQrImage(String token) {
// 生成二维码图片
// ...
}
}
@Entity
public class QrCode {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String token; // 随机 token
private BufferedImage qrImage; // 二维码图片
private boolean used = false; // 是否已经使用过
// getters/setters 省略
}
@Repository
public interface QrCodeRepository extends JpaRepository<QrCode, Long> {
QrCode findByToken(String token);
}
在这个例子中,生成二维码时会生成一个随机 token 并保存到数据库中,同时将生成的二维码图片返回给客户端。客户端扫码时,会将二维码中的 token 发送到服务器端进行验证。服务器端根据 token 从数据库中查找对应的二维码信息,如果二维码未被使用过,则将其状态设置为已使用,并更新到数据库中。否则,返回错误信息表示该二维码已经被使用过。这样就实现了只能使用一次就过期的功能。
2 . redis方法
大概思路,生成二维码的时候加上redis的key,然后设置这个键值过期时间,在消费时查询这个redis里面有没有这个key键值,没有就提示过期;有的话就删掉这个key
这个方法告诉前端,让他生成的时候帮你加上qrPcCodeId
public interface CommonConstant {
String LOGIN_PC_QRCODE = "LQPC:";
}
/**
* PC生成二维码
*/
@ApiOperation(value = "PC生成二维码", notes = "PC生成二维码")
@GetMapping("/getPcQrCode")
public Result<?> getPcQrcode() {
String qrPcCodeId = CommonConstant.LOGIN_PC_QRCODE + IdWorker.getIdStr();
//定义二维码参数
Map params = new HashMap(5);
params.put("qrPcCodeId", qrPcCodeId);
//存放二维码唯一标识24小时有效
redisUtil.set(CommonConstant.LOGIN_PC_QRCODE + qrPcCodeId, qrPcCodeId, 60 * 60 * 24);
return Result.OK(params);
}
然后在消费时监听key是否过期
public Result<?> getPcQrcode(String qrPcCodeId) {
Object check = redisUtil.get(CommonConstant.LOGIN_PC_QRCODE + qrPcCodeId);
if (!oConvertUtils.isNotEmpty(check)) {
return Result.Error(500, "二维码已过期,请刷新后重试");
}
//删除二维码缓存表示二维码过期
redisUtil.del(CommonConstant.LOGIN_PC_QRCODE + qrPcCodeId);
return Result.OK("消费成功");
}
博文仅提供思路和关键代码,剩下的还得要靠自己。如果各位老鸟发现博文有问题,欢迎指导一二