diff --git a/pom.xml b/pom.xml
index c36e621..93cea25 100644
--- a/pom.xml
+++ b/pom.xml
@@ -173,7 +173,7 @@
com.imyeyu.spring
timi-spring
- 0.0.17
+ 0.0.18
com.imyeyu.network
diff --git a/src/main/java/com/imyeyu/api/modules/gao/entity/GaoRegistrationEvent.java b/src/main/java/com/imyeyu/api/modules/gao/entity/GaoRegistrationEvent.java
index c627f26..40a792b 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/entity/GaoRegistrationEvent.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/entity/GaoRegistrationEvent.java
@@ -23,6 +23,9 @@ public class GaoRegistrationEvent extends UUIDEntity {
/// @since 2026-08-01
public enum Status {
+ /// 草稿,未发布不可登记
+ DRAFT,
+
/// 可登记
ACTIVE,
@@ -55,8 +58,11 @@ public class GaoRegistrationEvent extends UUIDEntity {
/// 每个自然月一次
NATURAL_MONTH,
- /// 累计限 N 次
- TOTAL_LIMIT
+ /// 事件总登记次数上限
+ TOTAL_LIMIT,
+
+ /// 单个客户总登记次数上限
+ CUSTOMER_TOTAL_LIMIT
}
/// 登记事件名称
@@ -71,9 +77,6 @@ public class GaoRegistrationEvent extends UUIDEntity {
/// 状态
private Status status;
- /// true 为启用
- private Boolean enabled;
-
/// true 为登记时要求拍照
private Boolean requirePhoto;
@@ -83,6 +86,12 @@ public class GaoRegistrationEvent extends UUIDEntity {
/// 登记限制数值,按限制类型表示小时数或次数
private Integer limitValue;
+ /// 可登记起始时间戳,毫秒,空为不限制
+ private Long beginAt;
+
+ /// 可登记终止时间戳,毫秒,空为不限制
+ private Long endAt;
+
/// 排序值
private Integer sort;
diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventMapper.java
index 196ae83..5ccd039 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventMapper.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventMapper.java
@@ -3,7 +3,6 @@ package com.imyeyu.api.modules.gao.mapper;
import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
import com.imyeyu.spring.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
import java.util.List;
@@ -16,6 +15,5 @@ public interface GaoRegistrationEventMapper extends BaseMapper selectByIdList(@Param("idList") List idList);
- @Select("SELECT * FROM `gao_registration_event` WHERE `enabled` = TRUE AND (`status` IS NULL OR `status` = 'ACTIVE') AND `deleted_at` IS NULL ORDER BY `sort` ASC, `created_at` ASC")
- List selectEnabledList();
+ List selectEnabledList(@Param("now") Long now);
}
diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventRecordMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventRecordMapper.java
index 31df65a..6862342 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventRecordMapper.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoRegistrationEventRecordMapper.java
@@ -43,6 +43,12 @@ public interface GaoRegistrationEventRecordMapper extends BaseMapper roleCodeList = registrationEventService.listRoleCode(registrationEvent.getId());
- if (roleCodeList != null && !roleCodeList.isEmpty()) {
- roleChecker.checkAny(ModuleCode.GAO, roleCodeList.toArray(String[]::new));
- }
+ TimiException.requiredTrue(roleCodeList != null && !roleCodeList.isEmpty(), "登记事件未配置可登记角色");
+ roleChecker.checkAny(ModuleCode.GAO, roleCodeList.toArray(String[]::new));
}
private void checkRegistrationEventCreatable(GaoRegistrationEvent registrationEvent, String customerId, long registeredAt) {
- TimiException.requiredTrue(Boolean.TRUE.equals(registrationEvent.getEnabled()), "登记事件未启用");
TimiException.requiredTrue(registrationEvent.getStatus() == null || registrationEvent.getStatus() == GaoRegistrationEvent.Status.ACTIVE, "登记事件不可登记");
+ TimiException.requiredTrue(registrationEvent.getBeginAt() == null || registrationEvent.getBeginAt() <= registeredAt, "登记事件未到可登记时间");
+ TimiException.requiredTrue(registrationEvent.getEndAt() == null || registeredAt <= registrationEvent.getEndAt(), "登记事件已过可登记时间");
GaoRegistrationEvent.LimitType limitType = TimiJava.defaultIfNull(registrationEvent.getLimitType(), GaoRegistrationEvent.LimitType.NONE);
switch (limitType) {
case DAILY_HALF_DAY -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getHalfDayBegin(registeredAt), getHalfDayEnd(registeredAt), "该客户当前半日已登记该事件");
case NATURAL_DAY -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getDayBegin(registeredAt), getDayEnd(registeredAt), "该客户当日已登记该事件");
case INTERVAL_HOUR -> checkIntervalHourRegistrationLimit(registrationEvent, customerId, registeredAt);
case NATURAL_MONTH -> checkRegistrationLimitRange(customerId, registrationEvent.getId(), getMonthBegin(registeredAt), getMonthEnd(registeredAt), "该客户当月已登记该事件");
- case TOTAL_LIMIT -> checkTotalRegistrationLimit(registrationEvent, customerId);
+ case TOTAL_LIMIT -> checkTotalRegistrationLimit(registrationEvent);
+ case CUSTOMER_TOTAL_LIMIT -> checkCustomerTotalRegistrationLimit(registrationEvent, customerId);
default -> {
}
}
@@ -345,13 +346,20 @@ public class GaoRegistrationEventRecordServiceImplement extends AbstractEntitySe
checkRegistrationLimitRange(customerId, registrationEvent.getId(), beginRegisteredAt, registeredAt, "该客户登记该事件间隔不足");
}
- private void checkTotalRegistrationLimit(GaoRegistrationEvent registrationEvent, String customerId) {
+ private void checkCustomerTotalRegistrationLimit(GaoRegistrationEvent registrationEvent, String customerId) {
Integer limitValue = registrationEvent.getLimitValue();
- TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件累计次数配置错误");
+ TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件单客户总次数配置错误");
Long count = mapper.countByCustomerIdAndRegistrationEventId(customerId, registrationEvent.getId());
TimiException.requiredTrue(TimiJava.defaultIfNull(count, 0L) < limitValue, "该客户登记该事件次数已达上限");
}
+ private void checkTotalRegistrationLimit(GaoRegistrationEvent registrationEvent) {
+ Integer limitValue = registrationEvent.getLimitValue();
+ TimiException.requiredTrue(limitValue != null && 0 < limitValue, "登记事件总次数配置错误");
+ Long count = mapper.countByRegistrationEventId(registrationEvent.getId());
+ TimiException.requiredTrue(TimiJava.defaultIfNull(count, 0L) < limitValue, "登记事件总次数已达上限");
+ }
+
private long getDayBegin(long registeredAt) {
ZoneId zoneId = ZoneId.systemDefault();
return Instant.ofEpochMilli(registeredAt).atZone(zoneId).toLocalDate().atStartOfDay(zoneId).toInstant().toEpochMilli();
diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoRegistrationEventServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoRegistrationEventServiceImplement.java
index b8809b7..1381064 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoRegistrationEventServiceImplement.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoRegistrationEventServiceImplement.java
@@ -6,11 +6,13 @@ import com.imyeyu.api.modules.gao.entity.GaoRegistrationEvent;
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventRoleRelationMapper;
import com.imyeyu.api.modules.gao.mapper.GaoRegistrationEventMapper;
import com.imyeyu.api.modules.gao.service.GaoRegistrationEventService;
+import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.bean.PageResult;
import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService;
+import com.imyeyu.utils.Time;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -61,7 +63,18 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
@Override
public void update(GaoRegistrationEvent entity) {
checkEntity(entity, true);
- super.update(entity);
+ GaoRegistrationEvent current = get(entity.getId());
+ current.setName(entity.getName());
+ current.setDescription(entity.getDescription());
+ current.setColor(entity.getColor());
+ current.setStatus(entity.getStatus());
+ current.setRequirePhoto(entity.getRequirePhoto());
+ current.setLimitType(entity.getLimitType());
+ current.setLimitValue(entity.getLimitValue());
+ current.setBeginAt(entity.getBeginAt());
+ current.setEndAt(entity.getEndAt());
+ current.setSort(entity.getSort());
+ mapper.update(current);
saveRoleRelation(entity.getId(), entity.getRoleCodeList());
}
@@ -70,7 +83,6 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
public void delete(String id) {
GaoRegistrationEvent entity = get(id);
entity.setStatus(GaoRegistrationEvent.Status.DELETED);
- entity.setEnabled(false);
super.update(entity);
}
@@ -83,8 +95,11 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
@Override
public List listEnabled() {
- List list = mapper.selectEnabledList();
+ List list = mapper.selectEnabledList(Time.now());
loadRegistrationEventLimit(list);
+ list = list.stream()
+ .filter(item -> !TimiJava.isEmpty(item.getRoleCodeList()))
+ .toList();
return list;
}
@@ -102,16 +117,18 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
if (entity.getStatus() == null) {
entity.setStatus(GaoRegistrationEvent.Status.ACTIVE);
}
- if (entity.getEnabled() == null) {
- entity.setEnabled(true);
- }
if (entity.getRequirePhoto() == null) {
entity.setRequirePhoto(false);
}
if (entity.getLimitType() == null) {
entity.setLimitType(GaoRegistrationEvent.LimitType.NONE);
}
+ TimiException.requiredTrue(
+ entity.getRoleCodeList() != null && entity.getRoleCodeList().stream().anyMatch(item -> item != null && !item.isBlank()),
+ "not found registrationEvent.roleCodeList"
+ );
checkRegistrationLimit(entity);
+ checkRegisterablePeriod(entity);
if (entity.getColor() != null) {
entity.setColor(entity.getColor().trim());
}
@@ -122,7 +139,8 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
private void checkRegistrationLimit(GaoRegistrationEvent entity) {
if (entity.getLimitType() == GaoRegistrationEvent.LimitType.INTERVAL_HOUR
- || entity.getLimitType() == GaoRegistrationEvent.LimitType.TOTAL_LIMIT) {
+ || entity.getLimitType() == GaoRegistrationEvent.LimitType.TOTAL_LIMIT
+ || entity.getLimitType() == GaoRegistrationEvent.LimitType.CUSTOMER_TOTAL_LIMIT) {
TimiException.required(entity.getLimitValue(), "not found registrationEvent.limitValue");
TimiException.requiredTrue(0 < entity.getLimitValue(), "registrationEvent.limitValue lte 0");
return;
@@ -130,6 +148,16 @@ public class GaoRegistrationEventServiceImplement extends AbstractEntityService<
entity.setLimitValue(null);
}
+ private void checkRegisterablePeriod(GaoRegistrationEvent entity) {
+ if (entity.getBeginAt() == null && entity.getEndAt() == null) {
+ return;
+ }
+ TimiException.requiredTrue(
+ entity.getBeginAt() == null || entity.getEndAt() == null || entity.getBeginAt() <= entity.getEndAt(),
+ "registrationEvent.beginAt gt registrationEvent.endAt"
+ );
+ }
+
private void saveRoleRelation(String registrationEventId, List roleCodeList) {
roleRelationMapper.deleteByRegistrationEventId(registrationEventId);
if (roleCodeList == null || roleCodeList.isEmpty()) {
diff --git a/src/main/resources/db/migration/timiserver/V21__adjust_gao_registration_event_rule.sql b/src/main/resources/db/migration/timiserver/V21__adjust_gao_registration_event_rule.sql
new file mode 100644
index 0000000..6052d40
--- /dev/null
+++ b/src/main/resources/db/migration/timiserver/V21__adjust_gao_registration_event_rule.sql
@@ -0,0 +1,7 @@
+ALTER TABLE `gao_registration_event`
+ DROP KEY `idx_gao_registration_event_status`,
+ DROP COLUMN `enabled`,
+ MODIFY COLUMN `status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '状态,DRAFT 草稿,ACTIVE 可登记,INACTIVE 不可登记,DELETED 已删除',
+ ADD COLUMN `begin_at` BIGINT NULL COMMENT '可登记起始时间戳,毫秒,空为不限制' AFTER `limit_value`,
+ ADD COLUMN `end_at` BIGINT NULL COMMENT '可登记终止时间戳,毫秒,空为不限制' AFTER `begin_at`,
+ ADD KEY `idx_gao_registration_event_status` (`status`, `deleted_at`, `sort`, `created_at`);
diff --git a/src/main/resources/mapper/timi-server/GaoRegistrationEventMapper.xml b/src/main/resources/mapper/timi-server/GaoRegistrationEventMapper.xml
index 8c53a1c..9709039 100644
--- a/src/main/resources/mapper/timi-server/GaoRegistrationEventMapper.xml
+++ b/src/main/resources/mapper/timi-server/GaoRegistrationEventMapper.xml
@@ -18,4 +18,16 @@
AND `deleted_at` IS NULL
+
+
diff --git a/src/main/resources/mapper/timi-server/GaoRegistrationEventRecordMapper.xml b/src/main/resources/mapper/timi-server/GaoRegistrationEventRecordMapper.xml
index ae8ec61..6160ed8 100644
--- a/src/main/resources/mapper/timi-server/GaoRegistrationEventRecordMapper.xml
+++ b/src/main/resources/mapper/timi-server/GaoRegistrationEventRecordMapper.xml
@@ -42,6 +42,15 @@
AND `deleted_at` IS NULL
+
+