diff --git a/pjcloud-common/pjcloud-common-security/src/main/java/com/bsd/pjcloud/common/security/util/SecurityUtils.java b/pjcloud-common/pjcloud-common-security/src/main/java/com/bsd/pjcloud/common/security/util/SecurityUtils.java index 741ab580..5d331ee1 100644 --- a/pjcloud-common/pjcloud-common-security/src/main/java/com/bsd/pjcloud/common/security/util/SecurityUtils.java +++ b/pjcloud-common/pjcloud-common-security/src/main/java/com/bsd/pjcloud/common/security/util/SecurityUtils.java @@ -95,6 +95,10 @@ public class SecurityUtils { */ public List getRoleIds() { Authentication authentication = getAuthentication(); + // 异步任务/定时任务无线程登录态时 authentication 为 null,不能直接 NPE + if (authentication == null || authentication.getAuthorities() == null) { + return new ArrayList<>(); + } Collection authorities = authentication.getAuthorities(); List roleIds = new ArrayList<>(); diff --git a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java index 45a8f5a0..c259aa25 100644 --- a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java +++ b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java @@ -40,6 +40,7 @@ import com.bsd.pjcloud.common.core.constant.CommonConstants; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.data.tenant.TenantContextHolder; +import com.bsd.pjcloud.common.security.util.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; @@ -2498,8 +2499,14 @@ public class SmHotelMidServiceImpl implements SmHotelMidService { } private SmHotelEntity requireLocalHotel(Long hotelId) { - // 手工维护房型/产品/日历:本地来源 + 部门数据隔离 - SmHotelEntity hotel = requireHotelInScope(hotelId); + // 手工维护:有登录态时走部门数据隔离;本地滚加等异步/定时任务无 Authentication,改走无 DataScope 查询 + SmHotelEntity hotel; + if (SecurityUtils.getAuthentication() != null) { + hotel = requireHotelInScope(hotelId); + } + else { + hotel = requireHotel(hotelId, false); + } if (!SmHotelDataSource.isLocal(hotel.getSheetName())) { throw new IllegalArgumentException("仅「本地」数据来源的酒店可手工维护房型/产品/日历"); } diff --git a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelSyncServiceImpl.java b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelSyncServiceImpl.java index caa44593..a35af70d 100644 --- a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelSyncServiceImpl.java +++ b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelSyncServiceImpl.java @@ -31,6 +31,9 @@ import com.bsd.pjcloud.common.security.util.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import java.time.LocalDate; @@ -216,7 +219,21 @@ public class SmHotelSyncServiceImpl implements SmHotelSyncService { } final Long tid = tenantId; final Long logId = logEntity.getId(); - EXECUTOR.execute(() -> TenantBroker.runAs(tid, id -> runLocalDailyRoll(logId))); + // 手动触发时把登录态拷到异步线程,避免 DataScope 读 Authentication 空指针;定时任务仍无登录态 + final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + EXECUTOR.execute(() -> { + try { + if (auth != null) { + SecurityContext ctx = SecurityContextHolder.createEmptyContext(); + ctx.setAuthentication(auth); + SecurityContextHolder.setContext(ctx); + } + TenantBroker.runAs(tid, id -> runLocalDailyRoll(logId)); + } + finally { + SecurityContextHolder.clearContext(); + } + }); return R.ok(logEntity, "已提交本地滚加"); }