限时折扣的执行计划

创建限时折扣活动, 折扣时间: 08:00 ~ 11:00

  1. 活动时间:2016-12-01 10:00:00 ~ 2016-12-10 10:00:00, 每天重复

生成的执行计划如下: 2016-12-02 08:00:00 ~ 2016-12-02 11:00:00 2016-12-03 08:00:00 ~ 2016-12-03 11:00:00 2016-12-04 08:00:00 ~ 2016-12-04 11:00:00 2016-12-05 08:00:00 ~ 2016-12-05 11:00:00 2016-12-06 08:00:00 ~ 2016-12-06 11:00:00 2016-12-07 08:00:00 ~ 2016-12-07 11:00:00 2016-12-08 08:00:00 ~ 2016-12-08 11:00:00 2016-12-09 08:00:00 ~ 2016-12-09 11:00:00

  1. 活动时间:2016-12-01 10:00:00 ~ 2016-12-30 10:00:00, 每天重复, 重复日期 1,2,4 代表周一、周二、周四

生成的执行计划如下: 2016-12-05 08:00:00 ~ 2016-12-05 11:00:00 2016-12-06 08:00:00 ~ 2016-12-06 11:00:00 2016-12-08 08:00:00 ~ 2016-12-08 11:00:00 2016-12-12 08:00:00 ~ 2016-12-12 11:00:00 2016-12-13 08:00:00 ~ 2016-12-13 11:00:00 2016-12-15 08:00:00 ~ 2016-12-15 11:00:00 2016-12-19 08:00:00 ~ 2016-12-19 11:00:00 2016-12-20 08:00:00 ~ 2016-12-20 11:00:00 2016-12-22 08:00:00 ~ 2016-12-22 11:00:00 2016-12-26 08:00:00 ~ 2016-12-26 11:00:00 2016-12-27 08:00:00 ~ 2016-12-27 11:00:00 2016-12-29 08:00:00 ~ 2016-12-29 11:00:00

  1. 活动时间:2016-12-01 10:00:00 ~ 2017-02-10 10:00:00, 每月重复, 重复日期9号

生成的执行计划如下: 2016-12-02 08:00:00 ~ 2016-12-02 11:00:00 2016-12-03 08:00:00 ~ 2016-12-03 11:00:00 2016-12-04 08:00:00 ~ 2016-12-04 11:00:00

/**
 * 活动开始时间
 */
private LocalDateTime startTime;

/**
 * 活动结束时间
 */
private LocalDateTime endTime;

/**
 * 限时折扣优惠规则
 */
private static final Integer EVERY_DAY = 1;
private static final Integer EVERY_MONTH = 2;
private static final Integer EVERY_WEEK = 3;

/**
 * 是否重复, 0: 不重复, 1: 重复
 */
private Integer isRepeat;

/**
 * 重复周期, 1: 每天, 2: 每月, 3: 每周
 */
private Integer repeatCycle;

/**
 * 重复周期数, 几号或者周几, 周类型用","分隔
 */
private String cycleValue;

/**
 * 起始时间
 */
private String startTime;

/**
 * 结束时间
 */
private String endTime;

private List<DiscountExecutePlan> generateExecutePlan() {
    Activity activity = getActivity();
    List<DiscountExecutePlan> executePlans = new ArrayList<>();

    if (AppConstants.NO.equals(isRepeat)) {
        executePlans.add(DiscountExecutePlan.of(activity.getId(), activity.getOwner(),
                activity.getStartTime(), activity.getEndTime()));
        return executePlans;
    }

    LocalTime startTime = LocalTime.parse(this.startTime, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime endTime = LocalTime.parse(this.endTime, DateTimeFormatter.ISO_LOCAL_TIME);

    if (EVERY_DAY.equals(repeatCycle)) {
        generateDayPlans(startTime, endTime, executePlans);
    } else if (EVERY_MONTH.equals(repeatCycle)) {
        generateMonthPlans(startTime, endTime, executePlans);
    } else if (EVERY_WEEK.equals(repeatCycle)) {
        generateWeekPlans(startTime, endTime, executePlans);
    }
    return executePlans;
}

private void generateDayPlans(LocalTime startTime, LocalTime endTime, List<DiscountExecutePlan> executePlans) {
    if (isAllDay()) {
        // 合并
    }
    LocalDateTime start = getActivity().getStartTime();
    while (start.isBefore(getActivity().getEndTime())) {
        addPlan(start, startTime, endTime, executePlans);
        start = start.plusDays(1);
    }
}

private void generateMonthPlans(LocalTime startTime, LocalTime endTime, List<DiscountExecutePlan> executePlans) {
    LocalDateTime start = getActivity().getStartTime().withDayOfMonth(Integer.parseInt(cycleValue));
    if (start.isBefore(getActivity().getStartTime())) {
        start.plusMonths(1);
    }
    while (start.isBefore(getActivity().getEndTime())) {
        addPlan(start, startTime, endTime, executePlans);
        start = start.plusMonths(1);
    }
}

private void generateWeekPlans(LocalTime startTime, LocalTime endTime, List<DiscountExecutePlan> executePlans) {
    LocalDateTime start =  getActivity().getStartTime().minusDays(7);
    int[] weekDays = Stream.of(cycleValue.split(",")).mapToInt(Integer::parseInt).toArray();
    while (start.isBefore(getActivity().getEndTime())) {
        for (int weekDay : weekDays) {
            LocalDateTime base = start.plusDays(weekDay + 7 - start.getDayOfWeek().getValue());
            addPlan(base, startTime, endTime, executePlans);
        }
        start = start.plusDays(7);
    }
    if (isAllDay()) {
        // 合并相邻的
    }
}

private void addPlan(LocalDateTime base, LocalTime startTime, LocalTime endTime, List<DiscountExecutePlan> executePlans) {
    LocalDateTime start = LocalDateTime.of(base.toLocalDate(), startTime);
    LocalDateTime end = LocalDateTime.of(base.toLocalDate(), endTime);
    if (start.isBefore(getActivity().getStartTime()) || end.isAfter(getActivity().getEndTime())) {
        return;
    }
    executePlans.add(DiscountExecutePlan.of(getActivity().getId(), getActivity().getOwner(),
            start, end));
}

private boolean isAllDay() {
    return startTime.equals("00:00") && endTime.equals("24:00");
}

public static void main(String[] args) {
    Activity activity = Activity.builder()
            .id(IdGenerator.activityId())
            .startTime(LocalDateTime.now().plusDays(2))
            .endTime(LocalDateTime.now().plusDays(60))
            .build();
    DiscountRule rule = DiscountRule.builder()
            .isRepeat(1)
            .repeatCycle(EVERY_DAY)
            .startTime("08:00")
            .endTime("10:00")
            .build();
    rule.setActivity(activity);
    List<DiscountExecutePlan> dayPlans = rule.generateExecutePlan();
    System.out.println(dayPlans);

    rule.setRepeatCycle(EVERY_MONTH);
    rule.setCycleValue("25");
    List<DiscountExecutePlan> monthPlans = rule.generateExecutePlan();
    System.out.println(monthPlans);

    rule.setRepeatCycle(EVERY_WEEK);
    rule.setCycleValue("1,2,4,6");
    List<DiscountExecutePlan> weekPlans = rule.generateExecutePlan();
    System.out.println(weekPlans);
}

results matching ""

    No results matching ""