package com.ruoyi.framework.impl;

import cn.hutool.core.convert.Convert;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.Context;
import org.noear.solon.validation.annotation.NoRepeatSubmit;
import org.noear.solon.validation.annotation.NoRepeatSubmitChecker;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;

/**
 * 防重复提交
 * @author ruoyi
 */
@Component
@Condition(onClass = RedissonClient.class)
public class NoRepeatSubmitCheckerImpl implements NoRepeatSubmitChecker {

    @Inject
    RedissonClient redissonClient;

    /**
     * 防重复提交
     * @param anno  防重复提交注解
     * @param ctx  请求上下文
     * @param submitHash  是否是重复提交的判断标准：根据注解中的 value()的类型（3种：请求头、请求参数、请求体）取值，将值使用 MD5消息摘要算法计算得出 submitHash值
     * @param limitSeconds  间隔时间（作为锁的释放时间）
     * @return  是否获取到了锁。false代表没有获取到锁，说明锁被 “上一次的相同请求” 抢了，即这一次请求是重复提交的请求，将抛出 ValidatorException 异常（请勿重复提交）
     */
    @Override
    public boolean check(NoRepeatSubmit anno, Context ctx, String submitHash, int limitSeconds) {
        try {
            return redissonClient.getLock(submitHash).tryLock(0L, Convert.toLong(limitSeconds, 1L), TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }

}
