diff --git a/pom.xml b/pom.xml
index f656a5d..f46456d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -230,6 +230,10 @@
spring-boot-starter-freemarker
${springboot.version}
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
org.springframework.boot
spring-boot-starter-data-mongodb
diff --git a/src/main/java/com/imyeyu/api/config/BeanConfig.java b/src/main/java/com/imyeyu/api/config/BeanConfig.java
index ad7f099..00a701e 100644
--- a/src/main/java/com/imyeyu/api/config/BeanConfig.java
+++ b/src/main/java/com/imyeyu/api/config/BeanConfig.java
@@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.imyeyu.utils.Time;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -22,6 +23,7 @@ public class BeanConfig {
@Bean
public ObjectMapper jackson() {
return JsonMapper.builder()
+ .addModule(new JavaTimeModule())
.serializationInclusion(JsonInclude.Include.NON_NULL)
.defaultDateFormat(Time.dateTime)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
diff --git a/src/main/java/com/imyeyu/api/config/WebConfig.java b/src/main/java/com/imyeyu/api/config/WebConfig.java
index 6357124..d457568 100644
--- a/src/main/java/com/imyeyu/api/config/WebConfig.java
+++ b/src/main/java/com/imyeyu/api/config/WebConfig.java
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.imyeyu.api.annotation.EnableSettingInterceptor;
import com.imyeyu.api.annotation.RequestRateLimitInterceptor;
import com.imyeyu.api.annotation.RequireCorePermissionInterceptor;
@@ -78,6 +79,7 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List> converters) {
JsonMapper jsonMapper = JsonMapper.builder()
+ .addModule(new JavaTimeModule())
// 设置默认属性包含规则:忽略 null 值
.serializationInclusion(JsonInclude.Include.NON_NULL)
// 日期格式化
diff --git a/src/main/java/com/imyeyu/api/modules/gao/entity/GaoCustomer.java b/src/main/java/com/imyeyu/api/modules/gao/entity/GaoCustomer.java
index 06403ec..a37ed88 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/entity/GaoCustomer.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/entity/GaoCustomer.java
@@ -1,5 +1,7 @@
package com.imyeyu.api.modules.gao.entity;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.JsonNode;
import com.imyeyu.api.modules.common.entity.Attachment;
import com.imyeyu.api.modules.user.entity.User;
@@ -9,6 +11,7 @@ import com.imyeyu.spring.entity.UUIDEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import java.time.LocalDate;
import java.util.List;
///
@@ -30,6 +33,18 @@ public class GaoCustomer extends UUIDEntity {
PHOTO
}
+ ///
+ /// 出生日期使用的历法
+ ///
+ public enum BirthdateCalendar {
+
+ /// 公历
+ SOLAR,
+
+ /// 农历
+ LUNAR
+ }
+
/// 客户编码
private String code;
@@ -42,6 +57,22 @@ public class GaoCustomer extends UUIDEntity {
/// 年龄
private Integer age;
+ /// 出生日期,数据库只保存公历日期
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate birthdate;
+
+ /// 出生日期录入时使用的历法
+ private BirthdateCalendar birthdateCalendar;
+
+ @JsonIgnore
+ @Transient
+ private boolean birthdateProvided;
+
+ public void setBirthdate(LocalDate birthdate) {
+ this.birthdate = birthdate;
+ this.birthdateProvided = true;
+ }
+
/// 电话
private String telephone;
diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoCustomerServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoCustomerServiceImplement.java
index e0d6d89..762989c 100644
--- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoCustomerServiceImplement.java
+++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoCustomerServiceImplement.java
@@ -40,6 +40,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
+import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
@@ -75,6 +76,13 @@ public class GaoCustomerServiceImplement extends AbstractEntityService page(Page page) {
+ PageResult result = super.page(page);
+ loadListTransient(result.getList());
+ return result;
+ }
+
@Override
public void create(GaoCustomer entity) {
Logger logger = new Logger(Logger.Module.GAO, "GAO_CUSTOMER_CREATE");
@@ -108,7 +116,14 @@ public class GaoCustomerServiceImplement extends AbstractEntityService customerList) {
+ if (customerList != null) {
+ customerList.forEach(this::refreshAge);
+ }
loadAttachmentList(customerList);
}
+ /// 根据出生日期计算当前周岁。出生日期为空时保留旧数据中的手工年龄。
+ private void refreshAge(GaoCustomer customer) {
+ if (customer.getBirthdate() == null) {
+ return;
+ }
+ LocalDate today = LocalDate.now();
+ TimiException.requiredTrue(!customer.getBirthdate().isAfter(today), "customer.birthdate invalid");
+ customer.setAge(Period.between(customer.getBirthdate(), today).getYears());
+ }
+
private void loadIntroducerCustomer(List customerList) {
if (customerList == null || customerList.isEmpty()) {
return;
@@ -536,6 +571,13 @@ public class GaoCustomerServiceImplement extends AbstractEntityService