|
@@ -12,9 +12,12 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
+import java.time.DayOfWeek;
|
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.temporal.TemporalAdjusters;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 签到配置服务(运营端)
|
|
* 签到配置服务(运营端)
|
|
@@ -28,11 +31,17 @@ public class CheckInConfigService {
|
|
|
|
|
|
|
|
private static final Long CONFIG_ID = 1L;
|
|
private static final Long CONFIG_ID = 1L;
|
|
|
|
|
|
|
|
|
|
+ /** 周期模式 → 周期起始星期映射(当前支持两种周期类型) */
|
|
|
|
|
+ private static final Map<String, DayOfWeek> PERIOD_START_DAY = Map.of(
|
|
|
|
|
+ "FRI_THU", DayOfWeek.FRIDAY,
|
|
|
|
|
+ "MON_SUN", DayOfWeek.MONDAY
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
private final CheckInConfigMapper checkinConfigMapper;
|
|
private final CheckInConfigMapper checkinConfigMapper;
|
|
|
private final CheckInPeriodMapper periodMapper;
|
|
private final CheckInPeriodMapper periodMapper;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 获取签到配置(不存在则初始化默认值)
|
|
|
|
|
|
|
+ * 获取签到配置(不存在则初始化默认值并生成周期)
|
|
|
*/
|
|
*/
|
|
|
public CheckInConfig getConfig() {
|
|
public CheckInConfig getConfig() {
|
|
|
CheckInConfig config = checkinConfigMapper.selectById(CONFIG_ID);
|
|
CheckInConfig config = checkinConfigMapper.selectById(CONFIG_ID);
|
|
@@ -51,37 +60,47 @@ public class CheckInConfigService {
|
|
|
.remark("签到送会员:每周期累计签到达标后发放奖励")
|
|
.remark("签到送会员:每周期累计签到达标后发放奖励")
|
|
|
.build();
|
|
.build();
|
|
|
checkinConfigMapper.insert(config);
|
|
checkinConfigMapper.insert(config);
|
|
|
|
|
+ regeneratePeriods(config);
|
|
|
}
|
|
}
|
|
|
return config;
|
|
return config;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 更新签到全局配置(自动根据活动时间和周期模式生成周期)
|
|
* 更新签到全局配置(自动根据活动时间和周期模式生成周期)
|
|
|
|
|
+ * <p>活动停用(enabled=0)时不生成周期;启用且活动时间或周期模式变化时,删除所有 PENDING 周期并重新生成;
|
|
|
|
|
+ * 周期区分信息(requiredDays/rewardMode/rewardDays/rewardLevel)变化时,同步更新到所有 PENDING 周期。
|
|
|
*/
|
|
*/
|
|
|
@Transactional
|
|
@Transactional
|
|
|
public CheckInConfig updateConfig(CheckInConfigRequest request) {
|
|
public CheckInConfig updateConfig(CheckInConfigRequest request) {
|
|
|
CheckInConfig config = getConfig();
|
|
CheckInConfig config = getConfig();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
boolean timeChanged = !java.util.Objects.equals(config.getStartTime(), request.getStartTime())
|
|
boolean timeChanged = !java.util.Objects.equals(config.getStartTime(), request.getStartTime())
|
|
|
|| !java.util.Objects.equals(config.getEndTime(), request.getEndTime());
|
|
|| !java.util.Objects.equals(config.getEndTime(), request.getEndTime());
|
|
|
boolean modeChanged = request.getCycleMode() != null && !request.getCycleMode().equals(config.getCycleMode());
|
|
boolean modeChanged = request.getCycleMode() != null && !request.getCycleMode().equals(config.getCycleMode());
|
|
|
-
|
|
|
|
|
|
|
+ boolean rewardChanged = !java.util.Objects.equals(config.getRequiredDays(), request.getRequiredDays())
|
|
|
|
|
+ || !java.util.Objects.equals(config.getRewardMode(), request.getRewardMode())
|
|
|
|
|
+ || !java.util.Objects.equals(config.getRewardDays(), request.getRewardDays())
|
|
|
|
|
+ || !java.util.Objects.equals(config.getRewardLevel(), request.getRewardLevel());
|
|
|
|
|
+
|
|
|
config.setEnabled(request.getEnabled());
|
|
config.setEnabled(request.getEnabled());
|
|
|
config.setStartTime(request.getStartTime());
|
|
config.setStartTime(request.getStartTime());
|
|
|
config.setEndTime(request.getEndTime());
|
|
config.setEndTime(request.getEndTime());
|
|
|
- if (request.getRewardLevel() != null) config.setRewardLevel(request.getRewardLevel());
|
|
|
|
|
- if (request.getCycleMode() != null) config.setCycleMode(request.getCycleMode());
|
|
|
|
|
- if (request.getRequiredDays() != null) config.setRequiredDays(request.getRequiredDays());
|
|
|
|
|
- if (request.getRewardMode() != null) config.setRewardMode(request.getRewardMode());
|
|
|
|
|
- if (request.getRewardDays() != null) config.setRewardDays(request.getRewardDays());
|
|
|
|
|
- if (request.getMaxRewardCount() != null) config.setMaxRewardCount(request.getMaxRewardCount());
|
|
|
|
|
- if (request.getRemark() != null) config.setRemark(request.getRemark());
|
|
|
|
|
|
|
+ config.setRewardLevel(request.getRewardLevel());
|
|
|
|
|
+ config.setCycleMode(request.getCycleMode());
|
|
|
|
|
+ config.setRequiredDays(request.getRequiredDays());
|
|
|
|
|
+ config.setRewardMode(request.getRewardMode());
|
|
|
|
|
+ config.setRewardDays(request.getRewardDays());
|
|
|
|
|
+ config.setMaxRewardCount(request.getMaxRewardCount());
|
|
|
|
|
+ config.setRemark(request.getRemark());
|
|
|
checkinConfigMapper.updateById(config);
|
|
checkinConfigMapper.updateById(config);
|
|
|
|
|
|
|
|
- if (timeChanged || modeChanged) {
|
|
|
|
|
|
|
+ boolean active = request.getEnabled() != null && request.getEnabled() == 1;
|
|
|
|
|
+ if (active && (timeChanged || modeChanged)) {
|
|
|
regeneratePeriods(config);
|
|
regeneratePeriods(config);
|
|
|
|
|
+ } else if (active && rewardChanged) {
|
|
|
|
|
+ updatePendingPeriodsConfig(config);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
log.info("签到全局配置已更新: enabled={}, cycleMode={}, requiredDays={}, rewardDays={}",
|
|
log.info("签到全局配置已更新: enabled={}, cycleMode={}, requiredDays={}, rewardDays={}",
|
|
|
config.getEnabled(), config.getCycleMode(), config.getRequiredDays(), config.getRewardDays());
|
|
config.getEnabled(), config.getCycleMode(), config.getRequiredDays(), config.getRewardDays());
|
|
|
return config;
|
|
return config;
|
|
@@ -110,106 +129,97 @@ public class CheckInConfigService {
|
|
|
|
|
|
|
|
generatePeriodsInRange(activityStart, activityEnd, cycleMode, config);
|
|
generatePeriodsInRange(activityStart, activityEnd, cycleMode, config);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将周期区分信息(requiredDays/rewardMode/rewardDays/rewardLevel)同步更新到所有 PENDING 周期
|
|
|
|
|
+ * <p>不删除重建,避免丢失 ACTIVE/CLOSED 周期的历史数据。
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional
|
|
|
|
|
+ public void updatePendingPeriodsConfig(CheckInConfig config) {
|
|
|
|
|
+ com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CheckInPeriod> wrapper =
|
|
|
|
|
+ new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(CheckInPeriod::getStatus, "PENDING");
|
|
|
|
|
+ List<CheckInPeriod> pendingPeriods = periodMapper.selectList(wrapper);
|
|
|
|
|
+ if (pendingPeriods.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (CheckInPeriod period : pendingPeriods) {
|
|
|
|
|
+ period.setRequiredDays(config.getRequiredDays());
|
|
|
|
|
+ period.setRewardMode(orDefault(config.getRewardMode(), "CUMULATIVE"));
|
|
|
|
|
+ period.setRewardDays(config.getRewardDays());
|
|
|
|
|
+ period.setRewardLevel(orDefault(config.getRewardLevel(), "PRO"));
|
|
|
|
|
+ periodMapper.updateById(period);
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("已同步{}个PENDING周期的区分信息", pendingPeriods.size());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 在指定时间范围内生成周期
|
|
* 在指定时间范围内生成周期
|
|
|
|
|
+ * <p>根据周期模式(FRI_THU / MON_SUN)定位每个周期的起始星期,每个周期固定7天。
|
|
|
|
|
+ * 第一个周期从活动开始日所在周的周期起始星期开始(用 previousOrSame 回溯到本周起始日,避免漏掉当前周期)。
|
|
|
*/
|
|
*/
|
|
|
private void generatePeriodsInRange(LocalDate start, LocalDate end, String cycleMode, CheckInConfig config) {
|
|
private void generatePeriodsInRange(LocalDate start, LocalDate end, String cycleMode, CheckInConfig config) {
|
|
|
- LocalDate current = start;
|
|
|
|
|
|
|
+ DayOfWeek periodStartDay = PERIOD_START_DAY.getOrDefault(cycleMode.toUpperCase(), DayOfWeek.MONDAY);
|
|
|
|
|
+ LocalDate periodStart = start.with(TemporalAdjusters.previousOrSame(periodStartDay));
|
|
|
int periodIndex = 1;
|
|
int periodIndex = 1;
|
|
|
-
|
|
|
|
|
- while (!current.isAfter(end)) {
|
|
|
|
|
- LocalDate periodStart;
|
|
|
|
|
- LocalDate periodEnd;
|
|
|
|
|
-
|
|
|
|
|
- if ("FRI_THU".equalsIgnoreCase(cycleMode)) {
|
|
|
|
|
- periodStart = getNextFriday(current);
|
|
|
|
|
- periodEnd = periodStart.plusDays(6);
|
|
|
|
|
- } else {
|
|
|
|
|
- periodStart = getNextMonday(current);
|
|
|
|
|
- periodEnd = periodStart.plusDays(6);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (periodStart.isAfter(end)) {
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ while (!periodStart.isAfter(end)) {
|
|
|
|
|
+ LocalDate periodEnd = periodStart.plusDays(6);
|
|
|
if (periodEnd.isAfter(end)) {
|
|
if (periodEnd.isAfter(end)) {
|
|
|
periodEnd = end;
|
|
periodEnd = end;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
CheckInPeriod period = CheckInPeriod.builder()
|
|
CheckInPeriod period = CheckInPeriod.builder()
|
|
|
- .periodName("第" + periodIndex + "周期(" + periodStart.getMonthValue() + "/" + periodStart.getDayOfMonth()
|
|
|
|
|
|
|
+ .periodName("第" + periodIndex + "周期(" + periodStart.getMonthValue() + "/" + periodStart.getDayOfMonth()
|
|
|
+ "~" + periodEnd.getMonthValue() + "/" + periodEnd.getDayOfMonth() + ")")
|
|
+ "~" + periodEnd.getMonthValue() + "/" + periodEnd.getDayOfMonth() + ")")
|
|
|
.cycleMode(cycleMode)
|
|
.cycleMode(cycleMode)
|
|
|
.startDate(periodStart)
|
|
.startDate(periodStart)
|
|
|
.endDate(periodEnd)
|
|
.endDate(periodEnd)
|
|
|
.requiredDays(config.getRequiredDays())
|
|
.requiredDays(config.getRequiredDays())
|
|
|
- .rewardMode(config.getRewardMode() != null ? config.getRewardMode() : "CUMULATIVE")
|
|
|
|
|
|
|
+ .rewardMode(orDefault(config.getRewardMode(), "CUMULATIVE"))
|
|
|
.rewardDays(config.getRewardDays())
|
|
.rewardDays(config.getRewardDays())
|
|
|
- .rewardLevel(config.getRewardLevel() != null ? config.getRewardLevel() : "PRO")
|
|
|
|
|
|
|
+ .rewardLevel(orDefault(config.getRewardLevel(), "PRO"))
|
|
|
.status(determineStatus(periodStart, periodEnd))
|
|
.status(determineStatus(periodStart, periodEnd))
|
|
|
.sort(periodIndex)
|
|
.sort(periodIndex)
|
|
|
.build();
|
|
.build();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
periodMapper.insert(period);
|
|
periodMapper.insert(period);
|
|
|
log.info("自动生成周期: {} {}~{}", period.getPeriodName(), periodStart, periodEnd);
|
|
log.info("自动生成周期: {} {}~{}", period.getPeriodName(), periodStart, periodEnd);
|
|
|
-
|
|
|
|
|
- current = periodEnd.plusDays(1);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ periodStart = periodStart.plusWeeks(1);
|
|
|
periodIndex++;
|
|
periodIndex++;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取下一个周五
|
|
|
|
|
- */
|
|
|
|
|
- private LocalDate getNextFriday(LocalDate date) {
|
|
|
|
|
- int dayOfWeek = date.getDayOfWeek().getValue();
|
|
|
|
|
- int daysUntilFriday = (5 - dayOfWeek + 7) % 7;
|
|
|
|
|
- if (daysUntilFriday == 0 && date.getDayOfWeek().getValue() != 5) {
|
|
|
|
|
- daysUntilFriday = 7;
|
|
|
|
|
- }
|
|
|
|
|
- return date.plusDays(daysUntilFriday == 0 ? 0 : daysUntilFriday);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取下一个周一
|
|
|
|
|
- */
|
|
|
|
|
- private LocalDate getNextMonday(LocalDate date) {
|
|
|
|
|
- int dayOfWeek = date.getDayOfWeek().getValue();
|
|
|
|
|
- int daysUntilMonday = (1 - dayOfWeek + 7) % 7;
|
|
|
|
|
- if (daysUntilMonday == 0 && date.getDayOfWeek().getValue() != 1) {
|
|
|
|
|
- daysUntilMonday = 7;
|
|
|
|
|
- }
|
|
|
|
|
- return date.plusDays(daysUntilMonday == 0 ? 0 : daysUntilMonday);
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 校验签到功能是否开启
|
|
|
|
|
|
|
+ * 校验签到功能是否在活动时间范围内(停用也可签到,只是不发奖励)
|
|
|
*/
|
|
*/
|
|
|
public void ensureEnabled() {
|
|
public void ensureEnabled() {
|
|
|
CheckInConfig config = getConfig();
|
|
CheckInConfig config = getConfig();
|
|
|
- if (config.getEnabled() == null || config.getEnabled() != 1) {
|
|
|
|
|
- throw new BusinessException(ErrorCode.BUSINESS_ERROR, "签到功能已关闭");
|
|
|
|
|
- }
|
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
- if (config.getStartTime() != null && now.isBefore(config.getStartTime())) {
|
|
|
|
|
|
|
+ if (isBeforeStart(config, now)) {
|
|
|
throw new BusinessException(ErrorCode.BUSINESS_ERROR, "签到活动尚未开始");
|
|
throw new BusinessException(ErrorCode.BUSINESS_ERROR, "签到活动尚未开始");
|
|
|
}
|
|
}
|
|
|
- if (config.getEndTime() != null && now.isAfter(config.getEndTime())) {
|
|
|
|
|
|
|
+ if (isAfterEnd(config, now)) {
|
|
|
throw new BusinessException(ErrorCode.BUSINESS_ERROR, "签到活动已结束");
|
|
throw new BusinessException(ErrorCode.BUSINESS_ERROR, "签到活动已结束");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 判断活动是否进行中
|
|
|
|
|
|
|
+ * 判断活动是否进行中(enabled=1 且在活动时间范围内)
|
|
|
*/
|
|
*/
|
|
|
public boolean isActive(CheckInConfig config) {
|
|
public boolean isActive(CheckInConfig config) {
|
|
|
if (config.getEnabled() == null || config.getEnabled() != 1) return false;
|
|
if (config.getEnabled() == null || config.getEnabled() != 1) return false;
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
- if (config.getStartTime() != null && now.isBefore(config.getStartTime())) return false;
|
|
|
|
|
- if (config.getEndTime() != null && now.isAfter(config.getEndTime())) return false;
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ return !isBeforeStart(config, now) && !isAfterEnd(config, now);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isBeforeStart(CheckInConfig config, LocalDateTime now) {
|
|
|
|
|
+ return config.getStartTime() != null && now.isBefore(config.getStartTime());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean isAfterEnd(CheckInConfig config, LocalDateTime now) {
|
|
|
|
|
+ return config.getEndTime() != null && now.isAfter(config.getEndTime());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ==========================================
|
|
// ==========================================
|
|
@@ -234,15 +244,15 @@ public class CheckInConfigService {
|
|
|
CheckInConfig config = getConfig();
|
|
CheckInConfig config = getConfig();
|
|
|
CheckInPeriod period = CheckInPeriod.builder()
|
|
CheckInPeriod period = CheckInPeriod.builder()
|
|
|
.periodName(request.getPeriodName())
|
|
.periodName(request.getPeriodName())
|
|
|
- .cycleMode(request.getCycleMode() != null ? request.getCycleMode() : config.getCycleMode())
|
|
|
|
|
|
|
+ .cycleMode(orDefault(request.getCycleMode(), config.getCycleMode()))
|
|
|
.startDate(request.getStartDate())
|
|
.startDate(request.getStartDate())
|
|
|
.endDate(request.getEndDate())
|
|
.endDate(request.getEndDate())
|
|
|
- .requiredDays(request.getRequiredDays() != null ? request.getRequiredDays() : config.getRequiredDays())
|
|
|
|
|
- .rewardMode(request.getRewardMode() != null ? request.getRewardMode() : config.getRewardMode())
|
|
|
|
|
- .rewardDays(request.getRewardDays() != null ? request.getRewardDays() : config.getRewardDays())
|
|
|
|
|
- .rewardLevel(request.getRewardLevel() != null ? request.getRewardLevel() : config.getRewardLevel())
|
|
|
|
|
|
|
+ .requiredDays(orDefault(request.getRequiredDays(), config.getRequiredDays()))
|
|
|
|
|
+ .rewardMode(orDefault(request.getRewardMode(), config.getRewardMode()))
|
|
|
|
|
+ .rewardDays(orDefault(request.getRewardDays(), config.getRewardDays()))
|
|
|
|
|
+ .rewardLevel(orDefault(request.getRewardLevel(), config.getRewardLevel()))
|
|
|
.status(determineStatus(request.getStartDate(), request.getEndDate()))
|
|
.status(determineStatus(request.getStartDate(), request.getEndDate()))
|
|
|
- .sort(request.getSort() != null ? request.getSort() : 0)
|
|
|
|
|
|
|
+ .sort(orDefault(request.getSort(), 0))
|
|
|
.build();
|
|
.build();
|
|
|
periodMapper.insert(period);
|
|
periodMapper.insert(period);
|
|
|
log.info("签到周期已创建: id={}, {}~{}", period.getId(), period.getStartDate(), period.getEndDate());
|
|
log.info("签到周期已创建: id={}, {}~{}", period.getId(), period.getStartDate(), period.getEndDate());
|
|
@@ -255,15 +265,15 @@ public class CheckInConfigService {
|
|
|
if (period == null) {
|
|
if (period == null) {
|
|
|
throw new BusinessException(ErrorCode.PARAM_ERROR, "周期不存在");
|
|
throw new BusinessException(ErrorCode.PARAM_ERROR, "周期不存在");
|
|
|
}
|
|
}
|
|
|
- if (request.getPeriodName() != null) period.setPeriodName(request.getPeriodName());
|
|
|
|
|
- if (request.getCycleMode() != null) period.setCycleMode(request.getCycleMode());
|
|
|
|
|
- if (request.getStartDate() != null) period.setStartDate(request.getStartDate());
|
|
|
|
|
- if (request.getEndDate() != null) period.setEndDate(request.getEndDate());
|
|
|
|
|
- if (request.getRequiredDays() != null) period.setRequiredDays(request.getRequiredDays());
|
|
|
|
|
- if (request.getRewardMode() != null) period.setRewardMode(request.getRewardMode());
|
|
|
|
|
- if (request.getRewardDays() != null) period.setRewardDays(request.getRewardDays());
|
|
|
|
|
- if (request.getRewardLevel() != null) period.setRewardLevel(request.getRewardLevel());
|
|
|
|
|
- if (request.getSort() != null) period.setSort(request.getSort());
|
|
|
|
|
|
|
+ period.setPeriodName(orDefault(request.getPeriodName(), period.getPeriodName()));
|
|
|
|
|
+ period.setCycleMode(orDefault(request.getCycleMode(), period.getCycleMode()));
|
|
|
|
|
+ period.setStartDate(orDefault(request.getStartDate(), period.getStartDate()));
|
|
|
|
|
+ period.setEndDate(orDefault(request.getEndDate(), period.getEndDate()));
|
|
|
|
|
+ period.setRequiredDays(orDefault(request.getRequiredDays(), period.getRequiredDays()));
|
|
|
|
|
+ period.setRewardMode(orDefault(request.getRewardMode(), period.getRewardMode()));
|
|
|
|
|
+ period.setRewardDays(orDefault(request.getRewardDays(), period.getRewardDays()));
|
|
|
|
|
+ period.setRewardLevel(orDefault(request.getRewardLevel(), period.getRewardLevel()));
|
|
|
|
|
+ period.setSort(orDefault(request.getSort(), period.getSort()));
|
|
|
period.setStatus(determineStatus(period.getStartDate(), period.getEndDate()));
|
|
period.setStatus(determineStatus(period.getStartDate(), period.getEndDate()));
|
|
|
periodMapper.updateById(period);
|
|
periodMapper.updateById(period);
|
|
|
log.info("签到周期已更新: id={}, {}~{}", period.getId(), period.getStartDate(), period.getEndDate());
|
|
log.info("签到周期已更新: id={}, {}~{}", period.getId(), period.getStartDate(), period.getEndDate());
|
|
@@ -283,4 +293,9 @@ public class CheckInConfigService {
|
|
|
if (today.isAfter(end)) return "CLOSED";
|
|
if (today.isAfter(end)) return "CLOSED";
|
|
|
return "ACTIVE";
|
|
return "ACTIVE";
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /** 值为 null 时返回默认值 */
|
|
|
|
|
+ private static <T> T orDefault(T value, T defaultValue) {
|
|
|
|
|
+ return value != null ? value : defaultValue;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|