侧边栏壁纸
博主头像
liuyiwuqing博主等级

心在哪里收获就在哪里

  • 累计撰写 22 篇文章
  • 累计创建 24 个标签
  • 累计收到 34 条评论

目 录CONTENT

文章目录

给博客添加文章访问验证码功能

liuyiwuqing
2023-03-22 / 6 评论 / 15 点赞 / 2,139 阅读 / 7,045 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2023-07-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
广告 广告

之前在网上看别人的技术文章时,往往看到一些写的很不错的文章,但是都设置了验证码访问,需要扫码关注公众号获取验证码输入之后才能浏览完整的文章内容,感觉这个功能太棒了,简直就是引流神器,于是乎,在某个闲暇周末自己动手改造了一下本人的博客实现了这么一个功能,至于为什么写这篇文章呢?是因为有小伙伴也想要实现这个功能,希望我能出一篇教程。好啦,废话不多说,直接干!

干之前还是先看下成品吧!
文章验证码演示
后台操作非常简单,只需要发布文章的时候选择自定义模板validation即可,完全不影响原有的密码功能,并且密码验证成功之后session记录
文章验证码操作

本功能实现所依赖的环境:

  1. 博客程序:halo1.6
  2. 博客主题:Joe2.0

本次修改主要包涵一下几点:

  1. 后端新增接口:生成注册码、检查注册码,新增定时任务:清理过期注册码
  2. 前端验证码提示框

一、后端修改部分:

1、RegistrationCode:run.halo.app.model.entity.RegistrationCode

package run.halo.app.model.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.GenericGenerator;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.model.enums.RegistrationCodeType;

/**
 * 注册码
 *
 * @author lywq
 * @date 2023/06/14 09:33
 **/
@Data
@Entity
@Table(name = "registration_codes", indexes = {@Index(name = "code_index", columnList = "code")})
@ToString
@EqualsAndHashCode(callSuper = true)
public class RegistrationCode extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id")
    @GenericGenerator(name = "custom-id",
        strategy = "run.halo.app.model.entity.support.CustomIdGenerator")
    private Integer id;

    /**
     * 注册码
     */
    @Column(name = "code", nullable = false, columnDefinition = "VARCHAR(50) COMMENT '注册码'")
    private String code;

    /**
     * 类型 0-通用,1-售卖,2-激励广告,3-微信公众号,4-微信小程序
     */
    @Column(name = "type", nullable = false, columnDefinition = "TINYINT(0) COMMENT '类型:0-通用,1-售卖,2-激励广告,3-微信公众号,4-微信小程序'")
    private RegistrationCodeType type;

    /**
     * 状态 0-未使用,1-已使用,-1-已失效
     */
    @Column(name = "status", nullable = false, columnDefinition = "TINYINT(0) COMMENT '状态 0-未使用,1-已使用,-1-已失效'")
    @ColumnDefault("0")
    private RegistrationCodeStatus status;

    /**
     * 用户名
     */
    @Column(name = "user_name", columnDefinition = "VARCHAR(50) COMMENT '用户名'")
    private String userName;
}

2、RegistrationCodeDTO:run.halo.app.model.dto.RegistrationCodeDTO

package run.halo.app.model.dto;

import lombok.Data;
import run.halo.app.model.dto.base.OutputConverter;
import run.halo.app.model.entity.RegistrationCode;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.model.enums.RegistrationCodeType;

/**
 * 注册码
 *
 * @author lywq
 * @date 2023/01/31 17:37
 **/
@Data
public class RegistrationCodeDTO implements OutputConverter<RegistrationCodeDTO, RegistrationCode> {

    /**
     * 主键
     */
    private Integer id;

    /**
     * 注册码
     */
    private String code;

    /**
     * 类型 0-通用,1-售卖,2-激励广告,3-微信公众号,4-微信小程序
     */
    private RegistrationCodeType type;

    /**
     * 状态 0-未使用,1-已使用,-1-已失效
     */
    private RegistrationCodeStatus status;

    /**
     * 用户名
     */
    private String userName;

}

3、RegistrationCodeParam:run.halo.app.model.params.RegistrationCodeParam

package run.halo.app.model.params;

import lombok.Data;
import run.halo.app.model.dto.base.InputConverter;
import run.halo.app.model.entity.RegistrationCode;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.model.enums.RegistrationCodeType;

/**
 * RegistrationCode param
 *
 * @author lywq
 * @date 2023/02/09 09:51
 **/
@Data
public class RegistrationCodeParam implements InputConverter<RegistrationCode> {

    /**
     * 主键
     */
    private Integer id;

    /**
     * 注册码
     */
    private String code;

    /**
     * 类型 0-通用,1-售卖,2-激励广告,3-微信公众号,4-微信小程序
     */
    private RegistrationCodeType type = RegistrationCodeType.COMMON;

    /**
     * 状态 0-未使用,1-已使用,-1-已失效
     */
    private RegistrationCodeStatus status = RegistrationCodeStatus.NOT_USED;

    /**
     * 用户名
     */
    private String userName;

    @Override
    public void update(RegistrationCode domain) {
        InputConverter.super.update(domain);
    }
}

4、RegistrationCodeStatus:run.halo.app.model.enums.RegistrationCodeStatus

package run.halo.app.model.enums;

/**
 * 注册码状态 枚举
 *
 * @author lywq
 * @date 2023/06/14 10:03
 **/
public enum RegistrationCodeStatus implements ValueEnum<Integer> {


    /**
     * 已失效
     */
    INVALIDATED(-1),

    /**
     * 未使用
     */
    NOT_USED(0),

    /**
     * 已使用
     */
    USED(1);

    private final int value;

    RegistrationCodeStatus(int value) {
        this.value = value;
    }

    @Override
    public Integer getValue() {
        return value;
    }
}

5、RegistrationCodeType:run.halo.app.model.enums.RegistrationCodeType

package run.halo.app.model.enums;

/**
 * 注册码类型  枚举
 *
 * @author lywq
 * @date 2023/06/14 09:37
 **/
public enum RegistrationCodeType implements ValueEnum<Integer> {


    /**
     * 通用
     */
    COMMON(0),

    /**
     * 售卖
     */
    SALE(1),

    /**
     * 激励广告
     */
    INCENTIVE_ADVERTISING(2),

    /**
     * 微信公众号
     */
    WECHAT_OFFICIAL_ACCOUNT(3),

    /**
     * 微信小程序
     */
    WECHAT_APPLET(4);

    private final int value;

    RegistrationCodeType(int value) {
        this.value = value;
    }

    @Override
    public Integer getValue() {
        return value;
    }
}

6、RegistrationCodeRepository:run.halo.app.repository.RegistrationCodeRepository

package run.halo.app.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.lang.NonNull;
import run.halo.app.model.entity.RegistrationCode;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.repository.base.BaseRepository;

/**
 * RegistrationCode repository
 *
 * @author lywq
 * @date 2023/01/31 18:13
 **/
public interface RegistrationCodeRepository
    extends BaseRepository<RegistrationCode, Integer>, JpaSpecificationExecutor<RegistrationCode> {

    @NonNull
    List<RegistrationCode> findAllByStatus(@NonNull RegistrationCodeStatus status);

}

7、RegistrationCodeService:run.halo.app.service.RegistrationCodeService

package run.halo.app.service;

import java.util.Collection;
import java.util.List;
import org.springframework.lang.NonNull;
import run.halo.app.model.dto.RegistrationCodeDTO;
import run.halo.app.model.entity.RegistrationCode;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.model.params.RegistrationCodeParam;
import run.halo.app.service.base.CrudService;

/**
 * 注册码接口
 *
 * @author lywq
 * @date 2023/06/14 10:20
 **/
public interface RegistrationCodeService extends CrudService<RegistrationCode, Integer> {

    @NonNull
    RegistrationCode createBy(@NonNull RegistrationCodeParam registrationCodeParam);

    RegistrationCode updateBy(@NonNull RegistrationCode registrationCode);

    RegistrationCode getBy(@NonNull String code);

    boolean existByCode(String code);

    @NonNull
    List<RegistrationCode> listAllBy(@NonNull RegistrationCodeStatus status);

    @NonNull
    List<RegistrationCode> removeByIds(@NonNull Collection<Integer> ids);

    RegistrationCodeDTO convertTo(@NonNull RegistrationCode registrationCode);

    boolean checkRegistrationCode(@NonNull String code);
}

8、RegistrationCodeServiceImpl:run.halo.app.service.impl.RegistrationCodeServiceImpl

package run.halo.app.service.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import run.halo.app.model.dto.RegistrationCodeDTO;
import run.halo.app.model.entity.RegistrationCode;
import run.halo.app.model.enums.RegistrationCodeStatus;
import run.halo.app.model.params.RegistrationCodeParam;
import run.halo.app.repository.RegistrationCodeRepository;
import run.halo.app.repository.base.BaseRepository;
import run.halo.app.service.RegistrationCodeService;
import run.halo.app.service.base.AbstractCrudService;
import run.halo.app.utils.RegistrationCodeUtil;

/**
 * 注册码接口
 *
 * @author lywq
 * @date 2023/06/14 10:57
 **/
@Service
public class RegistrationCodeServiceImpl extends AbstractCrudService<RegistrationCode, Integer>
    implements RegistrationCodeService {
    private final RegistrationCodeRepository registrationCodeRepository;

    protected RegistrationCodeServiceImpl(
        BaseRepository<RegistrationCode, Integer> repository,
        RegistrationCodeRepository registrationCodeRepository) {
        super(repository);
        this.registrationCodeRepository = registrationCodeRepository;
    }


    @Override
    public @NotNull RegistrationCode createBy(
        @NotNull RegistrationCodeParam registrationCodeParam) {
        Assert.notNull(registrationCodeParam, "RegistrationCode param must not be null");

        RegistrationCode registrationCode = registrationCodeParam.convertTo();

        List<RegistrationCode> registrationCodes = listAll();
        List<String> list =
            registrationCodes.stream().map(RegistrationCode::getCode).collect(Collectors.toList());

        String code = RegistrationCodeUtil.createRegistrationCode(list);
        registrationCode.setCode(code);
        return create(registrationCode);
    }

    @Override
    public RegistrationCode updateBy(@NotNull RegistrationCode registrationCode) {
        Assert.notNull(registrationCode, "RegistrationCode must not be null");
        return update(registrationCode);
    }

    @Override
    public RegistrationCode getBy(@NotNull String code) {
        RegistrationCode registrationCode = new RegistrationCode();
        registrationCode.setCode(code);
        registrationCode.setStatus(RegistrationCodeStatus.NOT_USED);
        return registrationCodeRepository.findOne(Example.of(registrationCode)).orElse(null);
    }

    @Override
    public boolean existByCode(String code) {
        Assert.hasText(code, "registrationCode must not be blank");
        RegistrationCode registrationCode = new RegistrationCode();
        registrationCode.setCode(code);
        registrationCode.setStatus(RegistrationCodeStatus.NOT_USED);
        return registrationCodeRepository.exists(Example.of(registrationCode));
    }


    @Override
    public List<RegistrationCode> listAllBy(RegistrationCodeStatus status) {
        Assert.notNull(status, "RegistrationCode status must not be null");

        return registrationCodeRepository.findAllByStatus(status);
    }

    @Override
    public List<RegistrationCode> removeByIds(Collection<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return ids.stream().map(this::removeById).collect(Collectors.toList());
    }

    @Override
    public RegistrationCodeDTO convertTo(@NotNull RegistrationCode registrationCode) {
        Assert.notNull(registrationCode, "RegistrationCode must not be null");
        return new RegistrationCodeDTO().convertFrom(registrationCode);
    }

    @Override
    public boolean checkRegistrationCode(String code) {
        RegistrationCode registrationCode = this.getBy(code);
        if (Objects.nonNull(registrationCode)) {
            registrationCode.setStatus(RegistrationCodeStatus.USED);
            this.updateBy(registrationCode);
            return true;
        } else {
            return false;
        }
    }
}
15
广告 广告

评论区