Рассчитать хиты за день - PullRequest
2 голосов
/ 19 января 2020

Мне нужна помощь для реализации хитов в день на основе выбранного пользователем пакета. Это то, что я сделал до сих пор, но он не работает должным образом:

Entity:

@Entity
@Table(name = "users")
public class UsersModel implements Serializable {

    @Column(name = "plan")
    private String plan;

    @Column(name = "plan_last_activity")
    @Convert(converter = LocalDateTimeConverter.class)
    private LocalDateTime planLastActivity;
}

Код:

public boolean calculateClickTimes() {

    String userName = SecurityUtils.getSubject().getPrincipal().toString();
    QueryDashboardHelper queryHelper = new QueryDashboardHelper();
    UsersModel user = queryHelper.getUserByUserName(userName);

    String plan = user.getPlan(); // silver/gold/platinum/diamond
    int todayHits = user.getTradesPerDay();
    LocalDateTime lastHit = user.getPlanLastActivity();

    LocalDateTime now = LocalDateTime.now();
    LocalDateTime tenSecondsLater = now.plusDays(1);

    long diff = ChronoUnit.DAYS.between(lastHit, tenSecondsLater);

    switch(plan) {

      case "diamond":

        if(diff >= 1 && todayHits >= 20) {
            todayHits = 0;
            return true;
        }       
        break;

      case "platinum":

        if(diff >= 1 && todayHits >= 15) {
            todayHits = 0;
            return true;
        }       
        break;  

      case "gold":

        if(diff >= 1 && todayHits >= 10) {
            todayHits = 0;
            return true;
        }             
        break;  

      case "silver":

        if(diff >= 1 && todayHits >= 5) {
            // User has clicked 5 times today
            todayHits = 0;
            return true;
        }
        break;

      default:

    }

    return false;
}

Общая идея заключается в том, что пользователи должны быть ограничены в выполнении обращений к веб-странице на основе выбранного пакета (серебро / золото / платина / алмаз) и на основе данных из базы данных plan, tradesPerDay и planLastActivity разрешенные хиты должны быть ограничены на текущий день. Можете ли вы дать мне несколько советов, как правильно реализовать этот код, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 22 января 2020

это скелет механизма предложения, который может дать вам представление об использовании Spring для обработки сценариев такого типа ios

Создать аннотацию, например TrackHit:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TrackHit{

}

и создайте аспект

@Aspect
@Component
public class HitTrackerAspect {
    private final HitTrackerService hitTrackerService;

    public HitTrackerAspect(HitTrackerService hitTrackerService) {
        this.hitTrackerService = hitTrackerService;
    }

    // annotation package also should provided if present e.g @annotation(x.y.TrackHit)
    @Around(value = "@annotation(TrackHit)")
    public Object TrackUserHit(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        TrackHit trackHit = method.getAnnotation(TrackHit.class);
        if(trackHit !=null){
            String userName = SecurityUtils.getSubject().getPrincipal().toString();
            if (userName!=null) {
                // hitTrack service is used to check user plan , logic implemented inside isUserAllowed method 
                // of HitTrackerService 
                boolean allowed = hitTrackerService.isUserAllowed(userName)
                if(allowed){
                    return proceedingJoinPoint.proceed();
                }
            }
        }
    }
}

в сервисах, которые должны быть вызваны пользователем, добавьте в него аннотацию TrackHit, аспект проверит, будет ли разрешено продолжаться

например, вызов последней цены ограничен аспектным логином и должен быть проверен перед вызовом

@Service
public class PriceInquiryService {

    @TrackHit
    public long getLatestPrice(Long itemCode){
        // latest price logic here 
    }
}
1 голос
/ 22 января 2020

Вы можете сделать это на уровне базы данных:

create table users (
    id bigint primary key ,
    plan character varying,
    trades_today int
);

insert into users (id, plan, trades_today)
values (1, 'diamond', 15),
       (2, 'silver', 5),
       (3, 'gold', 0);

with packages(package_type, max_hits) as (
    values ('diamond', 20),
           ('platinum', 15),
           ('gold', 10),
           ('silver', 5)
)

select u.id, trades_today < p.max_hits
from users u
inner join packages p on u.plan = p.package_type;

Это приводит к:

+--+--------+
|id|?column?|
+--+--------+
|1 |true    |
|2 |false   |
|3 |true    |
+--+--------+

Каждый раз, когда выполняется удар, счетчик увеличивается. Счетчик сбрасывается каждую полночь

...