Przeglądaj źródła

fix: OffsetDateTime.now() 依赖 JVM 默认时区导致 timestamp without time zone 列日期偏移8小时

- PaymentApplication 加 PostConstruct 全局设 TimeZone.setDefault(Asia/Shanghai)
- AutoFillMetaObjectHandler createdTime/updatedTime 自动填充改用 OffsetDateTime.now(ZONE_BEIJING)
- BillHandler.toOffsetDateTime 用 ZoneId.of(Asia/Shanghai) 替代 ZoneOffset.ofHours(8),兜底 now() 也传 ZONE_BEIJING
alphaH 2 tygodni temu
rodzic
commit
c9d190b3a6

+ 9 - 0
java/src/main/java/com/payment/platform/PaymentApplication.java

@@ -4,10 +4,19 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
+import jakarta.annotation.PostConstruct;
+import java.util.TimeZone;
+
 @SpringBootApplication
 @EnableScheduling
 public class PaymentApplication {
 
+    /** 全局默认时区设为北京时间 — 所有 OffsetDateTime.now() / Jackson 序列化统一使用 */
+    @PostConstruct
+    void setDefaultTimezone() {
+        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
+    }
+
     public static void main(String[] args) {
         SpringApplication.run(PaymentApplication.class, args);
         System.out.println("企业码后端启动成功");

+ 6 - 2
java/src/main/java/com/payment/platform/common/config/AutoFillMetaObjectHandler.java

@@ -7,13 +7,17 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
 import java.time.OffsetDateTime;
+import java.time.ZoneId;
 
 @Component
 public class AutoFillMetaObjectHandler implements MetaObjectHandler {
 
+    /** 北京时间 — 不依赖 JVM 默认时区,避免 "timestamp without time zone" 列偏移一天 */
+    private static final ZoneId ZONE_BEIJING = ZoneId.of("Asia/Shanghai");
+
     @Override
     public void insertFill(MetaObject metaObject) {
-        OffsetDateTime now = OffsetDateTime.now();
+        OffsetDateTime now = OffsetDateTime.now(ZONE_BEIJING);
         this.strictInsertFill(metaObject, "createdTime", OffsetDateTime.class, now);
         this.strictInsertFill(metaObject, "updatedTime", OffsetDateTime.class, now);
         // 自动填充 tenantId(仅当实体有该字段且值为 null 时)
@@ -30,7 +34,7 @@ public class AutoFillMetaObjectHandler implements MetaObjectHandler {
 
     @Override
     public void updateFill(MetaObject metaObject) {
-        this.strictUpdateFill(metaObject, "updatedTime", OffsetDateTime.class, OffsetDateTime.now());
+        this.strictUpdateFill(metaObject, "updatedTime", OffsetDateTime.class, OffsetDateTime.now(ZONE_BEIJING));
     }
 
     private Long getCurrentTenantId() {

+ 7 - 4
java/src/main/java/com/payment/platform/module/payment/notification/handler/BillHandler.java

@@ -32,6 +32,7 @@ import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
 import java.time.OffsetDateTime;
+import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -214,11 +215,11 @@ public class BillHandler extends BaseNotifyHandler {
             if (parsed != null) {
                 bill.setGmtBizCreate(parsed);
             } else if (existing == null) {
-                bill.setGmtBizCreate(OffsetDateTime.now());
+                bill.setGmtBizCreate(OffsetDateTime.now(ZONE_BEIJING));
                 log.warn("账单 gmt_biz_create 解析失败,使用当前时间兜底: pay_no={}, raw={}", payNo, gmtBizCreate);
             }
         } else if (existing == null) {
-            bill.setGmtBizCreate(OffsetDateTime.now());
+            bill.setGmtBizCreate(OffsetDateTime.now(ZONE_BEIJING));
         }
         if (StrUtil.isNotBlank(gmtRecievePay)) bill.setGmtRecievePay(toOffsetDateTime(gmtRecievePay));
         if (StrUtil.isNotBlank(peerPayAmount)) bill.setPeerPayAmount(toDecimal(peerPayAmount));
@@ -435,11 +436,13 @@ public class BillHandler extends BaseNotifyHandler {
         try { return new BigDecimal(val); } catch (NumberFormatException e) { return null; }
     }
 
+    private static final ZoneId ZONE_BEIJING = ZoneId.of("Asia/Shanghai");
+
     private static java.time.OffsetDateTime toOffsetDateTime(String val) {
         if (StrUtil.isBlank(val)) return null;
         try {
             return java.time.LocalDate.parse(val, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)
-                    .atStartOfDay(java.time.ZoneOffset.ofHours(8)).toOffsetDateTime();
+                    .atStartOfDay(ZONE_BEIJING).toOffsetDateTime();
         } catch (Exception e1) {
             try {
                 return java.time.OffsetDateTime.parse(val,
@@ -448,7 +451,7 @@ public class BillHandler extends BaseNotifyHandler {
                 try {
                     return java.time.LocalDateTime.parse(val,
                             java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
-                            .atOffset(java.time.ZoneOffset.ofHours(8));
+                            .atZone(ZONE_BEIJING).toOffsetDateTime();
                 } catch (Exception e3) {
                     return null;
                 }