update
This commit is contained in:
@@ -20,7 +20,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
<tomcat.version>11.0.25</tomcat.version>
|
<tomcat.version>11.0.26</tomcat.version>
|
||||||
<netty.version>4.2.18.Final</netty.version>
|
<netty.version>4.2.18.Final</netty.version>
|
||||||
<httpclient5.version>5.6.4</httpclient5.version>
|
<httpclient5.version>5.6.4</httpclient5.version>
|
||||||
<httpclient5-win.version>5.2.3</httpclient5-win.version>
|
<httpclient5-win.version>5.2.3</httpclient5-win.version>
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
<fasterxml.jackson.version>2.22.3</fasterxml.jackson.version>
|
<fasterxml.jackson.version>2.22.3</fasterxml.jackson.version>
|
||||||
<tools.jackson.version>3.2.3</tools.jackson.version>
|
<tools.jackson.version>3.2.3</tools.jackson.version>
|
||||||
<log4j2.version>2.26.1</log4j2.version>
|
<log4j2.version>2.26.1</log4j2.version>
|
||||||
|
<hibernate-validator.version>9.2.0.Beta1</hibernate-validator.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -92,8 +93,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-mail</artifactId>
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.validation</groupId>
|
||||||
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
|
<version>4.0.0-M1</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
@@ -183,7 +188,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
<version>4.6.1</version>
|
<version>4.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.eatthepath</groupId>
|
<groupId>com.eatthepath</groupId>
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ public enum EumnDaylightStatus {
|
|||||||
DUEOUT("DUEOUT","DUE_OUT"),
|
DUEOUT("DUEOUT","DUE_OUT"),
|
||||||
CANCELED("CANCELED","CANCELED"),
|
CANCELED("CANCELED","CANCELED"),
|
||||||
CANCELLED("CANCELLED","CANCELED"),
|
CANCELLED("CANCELLED","CANCELED"),
|
||||||
NO_SHOW("NO SHOW","CANCELED"),
|
NO_SHOW("No-Show", "NO_SHOW");
|
||||||
NOSHOW("NOSHOW","CANCELED");
|
|
||||||
|
|
||||||
private String key;
|
private String key;
|
||||||
private String value;
|
private String value;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.mgm.mcrm.apigateway.daylight.repositories.CfgCompRuleDao;
|
|||||||
import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService;
|
import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.AvailableRoomCountUpdatedHandler;
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.AvailableRoomCountUpdatedHandler;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.CompRuleLimitsExceededChangedHandler;
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.CompRuleLimitsExceededChangedHandler;
|
||||||
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.ReservationCustomFieldsNotificationHandler;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.ReservationNotificationHandler;
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.ReservationNotificationHandler;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.RoomTypeDateAvailabilityChangedHandler;
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.RoomTypeDateAvailabilityChangedHandler;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.services.DaylightWebhookFactory;
|
import com.mgm.mcrm.apigateway.daylight.webhook.services.DaylightWebhookFactory;
|
||||||
@@ -33,6 +34,8 @@ public class ConfigListener implements ApplicationListener<ApplicationStartedEve
|
|||||||
private BookingService bookingService;
|
private BookingService bookingService;
|
||||||
@Resource
|
@Resource
|
||||||
private DaylightApiService daylightApiService;
|
private DaylightApiService daylightApiService;
|
||||||
|
@Resource
|
||||||
|
private ReservationCustomFieldsNotificationHandler reservationCustomFieldsNotificationHandler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SslBundles sslBundles;
|
private SslBundles sslBundles;
|
||||||
@@ -49,6 +52,7 @@ public class ConfigListener implements ApplicationListener<ApplicationStartedEve
|
|||||||
DaylightWebhookFactory.registerHandler("AvailableRoomCountUpdated", new AvailableRoomCountUpdatedHandler(roomCriteriaDaylightService));
|
DaylightWebhookFactory.registerHandler("AvailableRoomCountUpdated", new AvailableRoomCountUpdatedHandler(roomCriteriaDaylightService));
|
||||||
//--Register Reservation Notification handlers
|
//--Register Reservation Notification handlers
|
||||||
DaylightWebhookFactory.registerHandler("ReservationNotification", new ReservationNotificationHandler(bookingService, daylightApiService));
|
DaylightWebhookFactory.registerHandler("ReservationNotification", new ReservationNotificationHandler(bookingService, daylightApiService));
|
||||||
|
DaylightWebhookFactory.registerHandler("ReservationCustomFieldsNotification", reservationCustomFieldsNotificationHandler);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
HttpSslSupport.setSkipValidation(daylightApiSetting.isSkipTrustValidation());
|
HttpSslSupport.setSkipValidation(daylightApiSetting.isSkipTrustValidation());
|
||||||
|
|||||||
+2
-2
@@ -6,13 +6,13 @@ import jakarta.annotation.Resource;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
//@RestController
|
||||||
public class DaylightTestController {
|
public class DaylightTestController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DaylightFetchConfigurationService daylightFetchConfigurationService;
|
private DaylightFetchConfigurationService daylightFetchConfigurationService;
|
||||||
|
|
||||||
@GetMapping("/test/fetch-daylight-config")
|
// @GetMapping("/test/fetch-daylight-config")
|
||||||
public BaseApiResponse<Void> testFetchDaylightConfiguration() {
|
public BaseApiResponse<Void> testFetchDaylightConfiguration() {
|
||||||
BaseApiResponse<Void> propertiesResponse = daylightFetchConfigurationService.fetchDaylightProperties();
|
BaseApiResponse<Void> propertiesResponse = daylightFetchConfigurationService.fetchDaylightProperties();
|
||||||
if (!propertiesResponse.isSuccess()) {
|
if (!propertiesResponse.isSuccess()) {
|
||||||
|
|||||||
+45
-6
@@ -4,8 +4,8 @@ import com.mgm.mcrm.apigateway.common.dtos.BaseApiResponse;
|
|||||||
import com.mgm.mcrm.apigateway.daylight.common.services.DaylightFetchConfigurationService;
|
import com.mgm.mcrm.apigateway.daylight.common.services.DaylightFetchConfigurationService;
|
||||||
import com.mgm.mcrm.apigateway.common.utils.LogUtil;
|
import com.mgm.mcrm.apigateway.common.utils.LogUtil;
|
||||||
import com.mgm.mcrm.apigateway.daylight.repositories.CfgDaylightConfigurationDao;
|
import com.mgm.mcrm.apigateway.daylight.repositories.CfgDaylightConfigurationDao;
|
||||||
import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
@@ -13,14 +13,17 @@ import org.springframework.scheduling.annotation.Scheduled;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
prefix = "daylight.scheduler",
|
||||||
|
name = "open",
|
||||||
|
havingValue = "true"
|
||||||
|
)
|
||||||
public class DaylightConfigurationScheduler {
|
public class DaylightConfigurationScheduler {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DaylightFetchConfigurationService daylightFetchConfigurationService;
|
private DaylightFetchConfigurationService daylightFetchConfigurationService;
|
||||||
@Resource
|
@Resource
|
||||||
private CfgDaylightConfigurationDao cfgDaylightConfigurationDao;
|
private CfgDaylightConfigurationDao cfgDaylightConfigurationDao;
|
||||||
@Resource
|
|
||||||
private DaylightApiService daylightApiService;
|
|
||||||
|
|
||||||
@Order(1)
|
@Order(1)
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
@@ -93,6 +96,33 @@ public class DaylightConfigurationScheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Order(4)
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void fetchResourceManagementRequestorsOnStartupIfMissing() {
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "Checking saved Daylight resource requestors on startup");
|
||||||
|
try {
|
||||||
|
if (!cfgDaylightConfigurationDao.existsSavedDaylightProperties()) {
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "No saved Daylight properties found, skip resource requestors startup fetch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfgDaylightConfigurationDao.existsSavedDaylightResourceRequestors()) {
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "Saved Daylight resource requestors found, skip startup fetch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtil.warn(DaylightConfigurationScheduler.class, "No saved Daylight resource requestors found, start startup fetch");
|
||||||
|
BaseApiResponse<Void> requestorResponse = daylightFetchConfigurationService.fetchResourceManagementRequestors();
|
||||||
|
if (requestorResponse.isSuccess()) {
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "Startup resource requestors completed: " + requestorResponse.getMessage());
|
||||||
|
} else {
|
||||||
|
LogUtil.warn(DaylightConfigurationScheduler.class, "Startup resource requestors failed: " + requestorResponse.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(DaylightConfigurationScheduler.class, "Startup resource requestors error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按配置的时间和时区执行,拉取 Daylight 配置数据,默认北京时间每天凌晨2点
|
* 按配置的时间和时区执行,拉取 Daylight 配置数据,默认北京时间每天凌晨2点
|
||||||
*/
|
*/
|
||||||
@@ -102,7 +132,7 @@ public class DaylightConfigurationScheduler {
|
|||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Start scheduled task: fetchDaylightAllData");
|
LogUtil.info(DaylightConfigurationScheduler.class, "Start scheduled task: fetchDaylightAllData");
|
||||||
try {
|
try {
|
||||||
// 1. 拉取 Properties
|
// 1. 拉取 Properties
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Step 1/3: Fetching properties...");
|
LogUtil.info(DaylightConfigurationScheduler.class, "Step 1/4: Fetching properties...");
|
||||||
BaseApiResponse<Void> propResponse = daylightFetchConfigurationService.fetchDaylightProperties();
|
BaseApiResponse<Void> propResponse = daylightFetchConfigurationService.fetchDaylightProperties();
|
||||||
if (propResponse.isSuccess()) {
|
if (propResponse.isSuccess()) {
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Properties completed: " + propResponse.getMessage());
|
LogUtil.info(DaylightConfigurationScheduler.class, "Properties completed: " + propResponse.getMessage());
|
||||||
@@ -111,7 +141,7 @@ public class DaylightConfigurationScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 拉取 Configuration
|
// 2. 拉取 Configuration
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Step 2/3: Fetching configurations...");
|
LogUtil.info(DaylightConfigurationScheduler.class, "Step 2/4: Fetching configurations...");
|
||||||
BaseApiResponse<Void> configResponse = daylightFetchConfigurationService.fetchDaylightConfiguration();
|
BaseApiResponse<Void> configResponse = daylightFetchConfigurationService.fetchDaylightConfiguration();
|
||||||
if (configResponse.isSuccess()) {
|
if (configResponse.isSuccess()) {
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Configurations completed: " + configResponse.getMessage());
|
LogUtil.info(DaylightConfigurationScheduler.class, "Configurations completed: " + configResponse.getMessage());
|
||||||
@@ -120,7 +150,7 @@ public class DaylightConfigurationScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 拉取 Block Codes
|
// 3. 拉取 Block Codes
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Step 3/3: Fetching block codes...");
|
LogUtil.info(DaylightConfigurationScheduler.class, "Step 3/4: Fetching block codes...");
|
||||||
BaseApiResponse<Void> blockResponse = daylightFetchConfigurationService.fetchDaylightBlockCodes();
|
BaseApiResponse<Void> blockResponse = daylightFetchConfigurationService.fetchDaylightBlockCodes();
|
||||||
if (blockResponse.isSuccess()) {
|
if (blockResponse.isSuccess()) {
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Block codes completed: " + blockResponse.getMessage());
|
LogUtil.info(DaylightConfigurationScheduler.class, "Block codes completed: " + blockResponse.getMessage());
|
||||||
@@ -128,6 +158,15 @@ public class DaylightConfigurationScheduler {
|
|||||||
LogUtil.warn(DaylightConfigurationScheduler.class, "Block codes failed: " + blockResponse.getMessage());
|
LogUtil.warn(DaylightConfigurationScheduler.class, "Block codes failed: " + blockResponse.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. 拉取 Resource Requestors
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "Step 4/4: Fetching resource requestors...");
|
||||||
|
BaseApiResponse<Void> requestorResponse = daylightFetchConfigurationService.fetchResourceManagementRequestors();
|
||||||
|
if (requestorResponse.isSuccess()) {
|
||||||
|
LogUtil.info(DaylightConfigurationScheduler.class, "Resource requestors completed: " + requestorResponse.getMessage());
|
||||||
|
} else {
|
||||||
|
LogUtil.warn(DaylightConfigurationScheduler.class, "Resource requestors failed: " + requestorResponse.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
LogUtil.info(DaylightConfigurationScheduler.class, "Scheduled task finished: fetchDaylightAllData");
|
LogUtil.info(DaylightConfigurationScheduler.class, "Scheduled task finished: fetchDaylightAllData");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.error(DaylightConfigurationScheduler.class, "Scheduled task error: " + e.getMessage());
|
LogUtil.error(DaylightConfigurationScheduler.class, "Scheduled task error: " + e.getMessage());
|
||||||
|
|||||||
+187
-2
@@ -1,6 +1,7 @@
|
|||||||
package com.mgm.mcrm.apigateway.daylight.common.services;
|
package com.mgm.mcrm.apigateway.daylight.common.services;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.mgm.mcrm.apigateway.basesetting.property.models.CfgProperties;
|
import com.mgm.mcrm.apigateway.basesetting.property.models.CfgProperties;
|
||||||
import com.mgm.mcrm.apigateway.basesetting.property.repositories.PropertyDao;
|
import com.mgm.mcrm.apigateway.basesetting.property.repositories.PropertyDao;
|
||||||
@@ -30,9 +31,12 @@ import java.time.format.DateTimeFormatter;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class DaylightFetchConfigurationService {
|
public class DaylightFetchConfigurationService {
|
||||||
@@ -41,6 +45,8 @@ public class DaylightFetchConfigurationService {
|
|||||||
private static final DateTimeFormatter UTC_UPDATED_AT_FORMATTER = DateTimeFormatter
|
private static final DateTimeFormatter UTC_UPDATED_AT_FORMATTER = DateTimeFormatter
|
||||||
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
|
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
|
||||||
.withZone(ZoneOffset.UTC);
|
.withZone(ZoneOffset.UTC);
|
||||||
|
private static final String RESOURCE_REQUESTOR_CONFIG_NAME = "ResourceRequestor";
|
||||||
|
private static final int RESOURCE_REQUESTOR_PAGE_SIZE = 200;
|
||||||
|
|
||||||
private final HttpProxyErrorHandler httpErrorHandler = new HttpProxyErrorHandler();
|
private final HttpProxyErrorHandler httpErrorHandler = new HttpProxyErrorHandler();
|
||||||
@Resource
|
@Resource
|
||||||
@@ -93,7 +99,7 @@ public class DaylightFetchConfigurationService {
|
|||||||
boolean hasSavedConfig = cfgDaylightConfigurationDao.existsSavedConfigurationByDlPropertyId(dlPropertyId);
|
boolean hasSavedConfig = cfgDaylightConfigurationDao.existsSavedConfigurationByDlPropertyId(dlPropertyId);
|
||||||
if (lastSync.isPresent() && hasSavedConfig) {
|
if (lastSync.isPresent() && hasSavedConfig) {
|
||||||
updatedAtParam = "&updatedAt="
|
updatedAtParam = "&updatedAt="
|
||||||
+ UTC_UPDATED_AT_FORMATTER.format(lastSync.get().getLastSyncAt().toInstant());
|
+ UTC_UPDATED_AT_FORMATTER.format(lastSync.get().getLastSyncAt().toInstant().minusSeconds(1));
|
||||||
log.info("Property {} incremental sync, updatedAt: {}", dlPropertyId, updatedAtParam);
|
log.info("Property {} incremental sync, updatedAt: {}", dlPropertyId, updatedAtParam);
|
||||||
} else {
|
} else {
|
||||||
if (lastSync.isPresent() && !hasSavedConfig) {
|
if (lastSync.isPresent() && !hasSavedConfig) {
|
||||||
@@ -506,7 +512,7 @@ public class DaylightFetchConfigurationService {
|
|||||||
.findByDlPropertyIdAndConfigName(dlPropertyId, "BlockCode");
|
.findByDlPropertyIdAndConfigName(dlPropertyId, "BlockCode");
|
||||||
if (lastSync.isPresent() && existingConfig != null) {
|
if (lastSync.isPresent() && existingConfig != null) {
|
||||||
updatedAtParam = "&updatedAt="
|
updatedAtParam = "&updatedAt="
|
||||||
+ UTC_UPDATED_AT_FORMATTER.format(lastSync.get().getLastSyncAt().toInstant());
|
+ UTC_UPDATED_AT_FORMATTER.format(lastSync.get().getLastSyncAt().toInstant().minusSeconds(1));
|
||||||
log.info("Property {} BlockCode incremental sync, updatedAt: {}", dlPropertyId, updatedAtParam);
|
log.info("Property {} BlockCode incremental sync, updatedAt: {}", dlPropertyId, updatedAtParam);
|
||||||
} else {
|
} else {
|
||||||
if (lastSync.isPresent() && existingConfig == null) {
|
if (lastSync.isPresent() && existingConfig == null) {
|
||||||
@@ -635,4 +641,183 @@ public class DaylightFetchConfigurationService {
|
|||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按 property 分页拉取资源请求人;首次全量同步,之后按成功同步时间增量合并。
|
||||||
|
*/
|
||||||
|
public BaseApiResponse<Void> fetchResourceManagementRequestors() {
|
||||||
|
BaseApiResponse<Void> response = new BaseApiResponse<>();
|
||||||
|
Date syncStartTime = new Date();
|
||||||
|
|
||||||
|
try {
|
||||||
|
TokenResponse daylightApiToken = daylightTokenService.getApiAccessToken();
|
||||||
|
if (daylightApiToken == null || StringUtils.isBlank(daylightApiToken.getAccessToken())) {
|
||||||
|
response.setSuccess(false);
|
||||||
|
response.setMessage("Invoke daylight token failed");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CfgProperties> allProperties = propertyDao.findByCategory("DAYLIGHT");
|
||||||
|
if (allProperties == null || allProperties.isEmpty()) {
|
||||||
|
response.setSuccess(false);
|
||||||
|
response.setMessage("No properties found with category 'DAYLIGHT'");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
int savedCount = 0;
|
||||||
|
List<String> failedProperties = new ArrayList<>();
|
||||||
|
for (CfgProperties property : allProperties) {
|
||||||
|
String dlPropertyId = property.getDlPropertyId();
|
||||||
|
if (StringUtils.isBlank(dlPropertyId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean fetchSuccess = false;
|
||||||
|
int recordCount = 0;
|
||||||
|
try {
|
||||||
|
CfgDaylightConfiguration existingConfig = cfgDaylightConfigurationDao
|
||||||
|
.findByDlPropertyIdAndConfigName(dlPropertyId, RESOURCE_REQUESTOR_CONFIG_NAME);
|
||||||
|
Optional<SysLogDaylightConfigurationSync> lastSync = syncLogDao
|
||||||
|
.findTopByConfigNameAndDlPropertyIdAndSyncStatusOrderByLastSyncAtDesc(
|
||||||
|
RESOURCE_REQUESTOR_CONFIG_NAME, dlPropertyId, "SUCCESS");
|
||||||
|
|
||||||
|
// 配置不存在时强制全量,两个日期条件均不传。
|
||||||
|
boolean isIncremental = existingConfig != null && lastSync.isPresent()
|
||||||
|
&& lastSync.get().getLastSyncAt() != null;
|
||||||
|
String dateParams = "";
|
||||||
|
if (isIncremental) {
|
||||||
|
String syncTime = DateTimeFormatter.ISO_INSTANT.format(lastSync.get().getLastSyncAt().toInstant().minusSeconds(1));
|
||||||
|
// 接口通过同一个 filter 接收两个日期条件,独立的日期 query 参数会被忽略。
|
||||||
|
dateParams = "&filter=auditData.lastUpdateTime=ge=" + syncTime
|
||||||
|
+ ",auditData.creationTime=ge=" + syncTime;
|
||||||
|
log.info("Property {} ResourceRequestor incremental sync, UTC time: {}", dlPropertyId, syncTime);
|
||||||
|
} else {
|
||||||
|
log.info("Property {} ResourceRequestor full sync, no audit date parameters", dlPropertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JSONObject> allResults = fetchResourceRequestorPages(
|
||||||
|
dlPropertyId, daylightApiToken.getAccessToken(), dateParams, response);
|
||||||
|
List<JSONObject> oldItems = existingConfig != null
|
||||||
|
&& StringUtils.isNotBlank(existingConfig.getConfigValue())
|
||||||
|
? JSON.parseArray(existingConfig.getConfigValue(), JSONObject.class)
|
||||||
|
: new ArrayList<>();
|
||||||
|
|
||||||
|
// 所有页面成功后才保存,增量没有变化时保留原配置。
|
||||||
|
if (!isIncremental || !allResults.isEmpty()) {
|
||||||
|
List<JSONObject> savedItems = allResults;
|
||||||
|
if (isIncremental) {
|
||||||
|
Map<String, JSONObject> mergedMap = new LinkedHashMap<>();
|
||||||
|
for (JSONObject item : oldItems) {
|
||||||
|
mergedMap.put(getConfigItemKey(item), item);
|
||||||
|
}
|
||||||
|
for (JSONObject item : allResults) {
|
||||||
|
mergedMap.put(getConfigItemKey(item), item);
|
||||||
|
}
|
||||||
|
savedItems = new ArrayList<>(mergedMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
CfgDaylightConfiguration config = existingConfig != null ? existingConfig : new CfgDaylightConfiguration();
|
||||||
|
config.setConfigName(RESOURCE_REQUESTOR_CONFIG_NAME);
|
||||||
|
config.setDlPropertyId(dlPropertyId);
|
||||||
|
if (config.getCreatedAt() == null) {
|
||||||
|
config.setCreatedAt(new Date());
|
||||||
|
}
|
||||||
|
config.setConfigValue(JSONObject.toJSONString(savedItems));
|
||||||
|
config.setUpdatedAt(new Date());
|
||||||
|
cfgDaylightConfigurationDao.save(config);
|
||||||
|
logConfigurationChanges("ResourceRequestor " + (isIncremental ? "incremental sync" : "full sync"),
|
||||||
|
dlPropertyId, RESOURCE_REQUESTOR_CONFIG_NAME, oldItems, savedItems);
|
||||||
|
savedCount++;
|
||||||
|
}
|
||||||
|
recordCount = allResults.size();
|
||||||
|
fetchSuccess = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
failedProperties.add(dlPropertyId);
|
||||||
|
log.warn("Property {} ResourceRequestor sync failed", dlPropertyId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SysLogDaylightConfigurationSync syncLog = new SysLogDaylightConfigurationSync();
|
||||||
|
syncLog.setConfigName(RESOURCE_REQUESTOR_CONFIG_NAME);
|
||||||
|
syncLog.setDlPropertyId(dlPropertyId);
|
||||||
|
syncLog.setLastSyncAt(syncStartTime);
|
||||||
|
syncLog.setSyncStatus(fetchSuccess ? "SUCCESS" : "FAILED");
|
||||||
|
syncLog.setRecordCount(recordCount);
|
||||||
|
syncLog.setCreatedAt(new Date());
|
||||||
|
syncLogDao.save(syncLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setSuccess(failedProperties.isEmpty());
|
||||||
|
response.setMessage("Fetched and saved " + savedCount + " resource requestor configuration entries."
|
||||||
|
+ (failedProperties.isEmpty() ? "" : " Failed properties: " + StringUtils.join(failedProperties, ",")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("ResourceRequestor sync failed", e);
|
||||||
|
response.setSuccess(false);
|
||||||
|
response.setMessage(e.getMessage());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<JSONObject> fetchResourceRequestorPages(String dlPropertyId, String accessToken,
|
||||||
|
String dateParams, BaseApiResponse<Void> response) throws Exception {
|
||||||
|
String apiUrl = daylightApiSetting.getServerUrl() + "/api-gateway/resource-management/v1/resource";
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("authorization", "Bearer " + accessToken);
|
||||||
|
headers.set("Ac-Property-Id", dlPropertyId);
|
||||||
|
List<JSONObject> allResults = new ArrayList<>();
|
||||||
|
int pageNum = 1;
|
||||||
|
Set<String> fetchedIds = new HashSet<>();
|
||||||
|
long totalCount;
|
||||||
|
do {
|
||||||
|
// 此接口的分页请求参数为 pageNumber;pageNum 会被忽略并重复返回第一页。
|
||||||
|
String queryString = "pageSize=" + RESOURCE_REQUESTOR_PAGE_SIZE + "&pageNumber=" + pageNum + dateParams;
|
||||||
|
log.info("Fetching ResourceRequestor page {} for Ac-Property-Id: {}, query: {}", pageNum, dlPropertyId, queryString);
|
||||||
|
ResponseEntity<byte[]> requestResponse = webProxyService.invokeRequest(
|
||||||
|
WebProxyService.DAYLIGHT_API, HttpMethod.GET, apiUrl, queryString, headers, new byte[0],
|
||||||
|
Duration.ofSeconds(daylightApiSetting.getApiTimeout()), httpErrorHandler).block();
|
||||||
|
if (requestResponse == null) {
|
||||||
|
throw new IllegalStateException("Http request server can not visit");
|
||||||
|
}
|
||||||
|
response.setStatusCode(requestResponse.getStatusCode().value());
|
||||||
|
if (!requestResponse.getStatusCode().is2xxSuccessful()) {
|
||||||
|
byte[] errorBody = requestResponse.getBody();
|
||||||
|
throw new IllegalStateException(errorBody != null
|
||||||
|
? new String(errorBody, StandardCharsets.UTF_8) : "ResourceRequestor request failed");
|
||||||
|
}
|
||||||
|
byte[] responseBody = requestResponse.getBody();
|
||||||
|
if (responseBody == null || responseBody.length == 0) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor response body is empty");
|
||||||
|
}
|
||||||
|
JSONObject responseJson = JSONObject.parseObject(new String(responseBody, StandardCharsets.UTF_8));
|
||||||
|
JSONArray results = responseJson != null ? responseJson.getJSONArray("results") : null;
|
||||||
|
JSONObject paging = responseJson != null ? responseJson.getJSONObject("paging") : null;
|
||||||
|
Long pageTotalCount = paging != null ? paging.getLong("totalCount") : null;
|
||||||
|
if (results == null || pageTotalCount == null || pageTotalCount < 0) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor response is missing valid results or paging.totalCount");
|
||||||
|
}
|
||||||
|
Integer responsePageNumber = paging.getInteger("pageNumber");
|
||||||
|
if (responsePageNumber != null && responsePageNumber != pageNum) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor requested page " + pageNum
|
||||||
|
+ " but received page " + responsePageNumber + "; pagination parameters were not applied");
|
||||||
|
}
|
||||||
|
totalCount = pageTotalCount;
|
||||||
|
log.info("ResourceRequestor response for Ac-Property-Id: {}, requestedPage={}, responsePage={}, pageCount={}, totalCount={}",
|
||||||
|
dlPropertyId, pageNum, responsePageNumber, results.size(), totalCount);
|
||||||
|
if (results.isEmpty() && allResults.size() < totalCount) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor returned an empty page before all records were fetched");
|
||||||
|
}
|
||||||
|
List<JSONObject> pageResults = results.toJavaList(JSONObject.class);
|
||||||
|
for (JSONObject item : pageResults) {
|
||||||
|
String id = item.getString("id");
|
||||||
|
if (StringUtils.isBlank(id) || !fetchedIds.add(id)) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor returned a missing or repeated resource id on page " + pageNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allResults.addAll(pageResults);
|
||||||
|
} while ((long) pageNum++ * RESOURCE_REQUESTOR_PAGE_SIZE < totalCount);
|
||||||
|
|
||||||
|
if (allResults.size() != totalCount) {
|
||||||
|
throw new IllegalStateException("ResourceRequestor returned a record count different from paging.totalCount");
|
||||||
|
}
|
||||||
|
return allResults;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -17,7 +17,7 @@ public interface CfgDaylightConfigurationDao extends JpaRepository<CfgDaylightCo
|
|||||||
|
|
||||||
@Query("select case when count(c) > 0 then true else false end "
|
@Query("select case when count(c) > 0 then true else false end "
|
||||||
+ "from CfgDaylightConfiguration c "
|
+ "from CfgDaylightConfiguration c "
|
||||||
+ "where c.configName not in ('Property', 'BlockCode') "
|
+ "where c.configName not in ('Property', 'BlockCode', 'ResourceRequestor') "
|
||||||
+ "and c.configValue is not null "
|
+ "and c.configValue is not null "
|
||||||
+ "and c.configValue <> ''")
|
+ "and c.configValue <> ''")
|
||||||
boolean existsSavedDaylightConfiguration();
|
boolean existsSavedDaylightConfiguration();
|
||||||
@@ -25,7 +25,7 @@ public interface CfgDaylightConfigurationDao extends JpaRepository<CfgDaylightCo
|
|||||||
@Query("select case when count(c) > 0 then true else false end "
|
@Query("select case when count(c) > 0 then true else false end "
|
||||||
+ "from CfgDaylightConfiguration c "
|
+ "from CfgDaylightConfiguration c "
|
||||||
+ "where c.dlPropertyId = ?1 "
|
+ "where c.dlPropertyId = ?1 "
|
||||||
+ "and c.configName not in ('Property', 'BlockCode') "
|
+ "and c.configName not in ('Property', 'BlockCode', 'ResourceRequestor') "
|
||||||
+ "and c.configValue is not null "
|
+ "and c.configValue is not null "
|
||||||
+ "and c.configValue <> ''")
|
+ "and c.configValue <> ''")
|
||||||
boolean existsSavedConfigurationByDlPropertyId(String dlPropertyId);
|
boolean existsSavedConfigurationByDlPropertyId(String dlPropertyId);
|
||||||
@@ -36,4 +36,11 @@ public interface CfgDaylightConfigurationDao extends JpaRepository<CfgDaylightCo
|
|||||||
+ "and c.configValue is not null "
|
+ "and c.configValue is not null "
|
||||||
+ "and c.configValue <> ''")
|
+ "and c.configValue <> ''")
|
||||||
boolean existsSavedDaylightBlockCodes();
|
boolean existsSavedDaylightBlockCodes();
|
||||||
|
|
||||||
|
@Query("select case when count(c) > 0 then true else false end "
|
||||||
|
+ "from CfgDaylightConfiguration c "
|
||||||
|
+ "where c.configName = 'ResourceRequestor' "
|
||||||
|
+ "and c.configValue is not null "
|
||||||
|
+ "and c.configValue <> ''")
|
||||||
|
boolean existsSavedDaylightResourceRequestors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class DaylightApiService {
|
|||||||
BaseApiResponse<JSONObject> result = new BaseApiResponse<>();
|
BaseApiResponse<JSONObject> result = new BaseApiResponse<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = "/api-gateway/booking/v1/reservations/" + dlReservationId + "?extend=PurchaseElements,CustomFields";
|
String url = "/api-gateway/booking/v1/reservations/" + dlReservationId + "?extend=CustomFields";
|
||||||
// 获取对应的值
|
// 获取对应的值
|
||||||
Header[] headers = HttpHeaderBuilder.custom()
|
Header[] headers = HttpHeaderBuilder.custom()
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ReservationCustomFieldsNotificationEvent {
|
||||||
|
private String reservationId;
|
||||||
|
private String trigger;
|
||||||
|
private CustomFieldsState previous;
|
||||||
|
private CustomFieldsState current;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class CustomFieldsState {
|
||||||
|
private List<CustomField> customFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class CustomField {
|
||||||
|
private String location;
|
||||||
|
private String value;
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ReservationHeaderCustomFields {
|
||||||
|
@JSONField(name = "Booker")
|
||||||
|
private String booker;
|
||||||
|
|
||||||
|
@JSONField(name = "Approver")
|
||||||
|
private String approver;
|
||||||
|
|
||||||
|
@JSONField(name = "App_Rea")
|
||||||
|
private String approvalReason;
|
||||||
|
|
||||||
|
@JSONField(name = "WAIVEDEPOSIT", alternateNames = {"WAIVEDPOSIT"})
|
||||||
|
private String waiveDeposit;
|
||||||
|
}
|
||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.mgm.mcrm.apigateway.common.dtos.BaseApiResponse;
|
||||||
|
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.ReservationCustomFieldsNotificationEvent;
|
||||||
|
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.ReservationCustomFieldsNotificationEvent.CustomField;
|
||||||
|
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.ReservationHeaderCustomFields;
|
||||||
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.DaylightWebhookHandler;
|
||||||
|
import com.mgm.mcrm.apigateway.reservation.models.Bookings;
|
||||||
|
import com.mgm.mcrm.apigateway.reservation.repositories.BookingDao;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ReservationCustomFieldsNotificationHandler implements DaylightWebhookHandler {
|
||||||
|
|
||||||
|
private final BookingDao bookingDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseApiResponse<Void> handle(String payload, Map<String, String> headers) throws InterruptedException {
|
||||||
|
BaseApiResponse<Void> result = new BaseApiResponse<>();
|
||||||
|
ReservationCustomFieldsNotificationEvent eventData;
|
||||||
|
try {
|
||||||
|
eventData = JSONObject.parseObject(payload, ReservationCustomFieldsNotificationEvent.class);
|
||||||
|
} catch (Exception err) {
|
||||||
|
result.setMessage("Convert Payload failed:[" + err.getMessage() + "]");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventData == null || StringUtils.isBlank(eventData.getReservationId())) {
|
||||||
|
result.setMessage("Empty reservationId for this event");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(8);
|
||||||
|
} catch (InterruptedException err) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
String reservationId = eventData.getReservationId();
|
||||||
|
List<Bookings> bookings = bookingDao.findByDlReservationId(reservationId);
|
||||||
|
Bookings booking = null;
|
||||||
|
if (!CollectionUtils.isEmpty(bookings)) {
|
||||||
|
for (Bookings candidate : bookings) {
|
||||||
|
if ("N".equals(candidate.getApproveStatus())) {
|
||||||
|
booking = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (booking == null) {
|
||||||
|
log.warn("No booking with approveStatus=N for reservationId={}", reservationId);
|
||||||
|
result.setMessage("No booking with approveStatus=N for reservationId[" + reservationId + "]");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventData.getCurrent() == null || CollectionUtils.isEmpty(eventData.getCurrent().getCustomFields())) {
|
||||||
|
result.setMessage("Empty current.customFields for this event");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomField reservationHeader = eventData.getCurrent().getCustomFields().stream()
|
||||||
|
.filter(field -> field != null && "ReservationHeader".equals(field.getLocation()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (reservationHeader == null || StringUtils.isBlank(reservationHeader.getValue())) {
|
||||||
|
result.setMessage("Empty ReservationHeader value for this event");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReservationHeaderCustomFields customFields;
|
||||||
|
Long approvedId;
|
||||||
|
try {
|
||||||
|
customFields = JSONObject.parseObject(reservationHeader.getValue(), ReservationHeaderCustomFields.class);
|
||||||
|
if (customFields == null) {
|
||||||
|
result.setMessage("Empty ReservationHeader value for this event");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
approvedId = StringUtils.isBlank(customFields.getApprover())
|
||||||
|
? null : Long.valueOf(customFields.getApprover().trim());
|
||||||
|
} catch (Exception err) {
|
||||||
|
result.setMessage("Convert ReservationHeader value failed:[" + err.getMessage() + "]");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
booking.setCreatedBy(customFields.getBooker());
|
||||||
|
booking.setBooker(customFields.getBooker());
|
||||||
|
booking.setApprovalReason(customFields.getApprovalReason());
|
||||||
|
booking.setApprovedId(approvedId);
|
||||||
|
bookingDao.save(booking);
|
||||||
|
|
||||||
|
log.info("Updated reservation custom fields for bookingId={}, reservationId={}", booking.getId(), reservationId);
|
||||||
|
result.setSuccess(true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
-44
@@ -10,11 +10,13 @@ import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService;
|
|||||||
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.ReservationNotificationEvent;
|
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.ReservationNotificationEvent;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.StatusCodeEntity;
|
import com.mgm.mcrm.apigateway.daylight.webhook.dtos.reservation.StatusCodeEntity;
|
||||||
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.DaylightWebhookHandler;
|
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.DaylightWebhookHandler;
|
||||||
|
//import com.mgm.mcrm.apigateway.logging.services.SysBookingCacheService;
|
||||||
import com.mgm.mcrm.apigateway.reservation.models.Bookings;
|
import com.mgm.mcrm.apigateway.reservation.models.Bookings;
|
||||||
import com.mgm.mcrm.apigateway.reservation.services.BookingService;
|
import com.mgm.mcrm.apigateway.reservation.services.BookingService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Strings;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -32,6 +34,8 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
|
|||||||
|
|
||||||
private final DaylightApiService daylightApiService;
|
private final DaylightApiService daylightApiService;
|
||||||
|
|
||||||
|
// private final SysBookingCacheService sysBookingCacheService;
|
||||||
|
|
||||||
@Value("${daylight.system-id}")
|
@Value("${daylight.system-id}")
|
||||||
private String systemId;
|
private String systemId;
|
||||||
|
|
||||||
@@ -103,7 +107,17 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
|
|||||||
|
|
||||||
StatusCodeEntity statusCode = eventData.getStatusCode();
|
StatusCodeEntity statusCode = eventData.getStatusCode();
|
||||||
if(statusCode!=null) {
|
if(statusCode!=null) {
|
||||||
result.setLastOperaStatus(EumnDaylightStatus.getStatusByDaylightStatus(statusCode.getDescription().toUpperCase()));
|
String lastOperaStatus = EumnDaylightStatus.getStatusByDaylightStatus(statusCode.getDescription().toUpperCase());
|
||||||
|
|
||||||
|
result.setLastOperaStatus(lastOperaStatus);
|
||||||
|
|
||||||
|
if (Strings.CI.equalsAny(lastOperaStatus, "RESERVED", "CHECKED_IN", "DUE_IN")) {
|
||||||
|
result.setApproveStatus("N");
|
||||||
|
} else if ("CANCELED".equalsIgnoreCase(lastOperaStatus)) {
|
||||||
|
result.setApproveStatus("C");
|
||||||
|
} else {
|
||||||
|
result.setApproveStatus("N");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.setDlPropertyId(eventData.getPropertyId());
|
result.setDlPropertyId(eventData.getPropertyId());
|
||||||
result.setDlRoomTypeId(eventData.getRoomTypeId());
|
result.setDlRoomTypeId(eventData.getRoomTypeId());
|
||||||
@@ -113,49 +127,53 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
|
|||||||
String etaTime = dateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
String etaTime = dateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
||||||
result.setEta(etaTime);
|
result.setEta(etaTime);
|
||||||
}
|
}
|
||||||
BaseApiResponse<JSONObject> response =
|
// BaseApiResponse<JSONObject> response =
|
||||||
daylightApiService.getDaylightReservationByDlId(eventData.getReservationId(), eventData.getPropertyId());
|
// daylightApiService.getDaylightReservationByDlId(eventData.getReservationId(), eventData.getPropertyId());
|
||||||
|
//
|
||||||
if (response.isSuccess() && Objects.nonNull(response.getData())) {
|
// if (response.isSuccess()) {
|
||||||
JSONObject embedded = response.getData().getJSONObject("_embedded");
|
// if (Objects.nonNull(response.getData())) {
|
||||||
if (embedded != null) {
|
// JSONObject embedded = response.getData().getJSONObject("_embedded");
|
||||||
JSONArray customFields = embedded.getJSONArray("customFields");
|
// if (embedded != null) {
|
||||||
|
// JSONArray customFields = embedded.getJSONArray("customFields");
|
||||||
if (customFields != null) {
|
//
|
||||||
for (int j = 0; j < customFields.size(); j++) {
|
// if (customFields != null) {
|
||||||
JSONObject jsonObject = customFields.getJSONObject(j);
|
// for (int j = 0; j < customFields.size(); j++) {
|
||||||
String value = jsonObject.getString("value");
|
// JSONObject jsonObject = customFields.getJSONObject(j);
|
||||||
JSONObject valueJson = JSONObject.parseObject(value);
|
// String value = jsonObject.getString("value");
|
||||||
String booker = valueJson.getString("Booker");
|
// JSONObject valueJson = JSONObject.parseObject(value);
|
||||||
|
// String booker = valueJson.getString("Booker");
|
||||||
if (StringUtils.isNotBlank(booker)) {
|
//
|
||||||
result.setCreatedBy(booker);
|
// if (StringUtils.isNotBlank(booker)) {
|
||||||
result.setBooker(booker);
|
// result.setCreatedBy(booker);
|
||||||
}
|
// result.setBooker(booker);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
if (StringUtils.isBlank(result.getDlExternalNo())) {
|
//
|
||||||
JSONArray jsonArray = response.getData().getJSONArray("externalIds");
|
// if (StringUtils.isBlank(result.getDlExternalNo())) {
|
||||||
if (!CollectionUtils.isEmpty(jsonArray)) {
|
// JSONArray jsonArray = response.getData().getJSONArray("externalIds");
|
||||||
|
// if (!CollectionUtils.isEmpty(jsonArray)) {
|
||||||
for (int i = 0; i < jsonArray.size(); i++) {
|
//
|
||||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
// for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
// JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||||
if (jsonObject.getString("systemId").equals(systemId)) {
|
//
|
||||||
result.setDlExternalNo(jsonObject.getString("number"));
|
// if (jsonObject.getString("systemId").equals(systemId)) {
|
||||||
break;
|
// result.setDlExternalNo(jsonObject.getString("number"));
|
||||||
}
|
// break;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
if (StringUtils.isBlank(result.getDlExternalNo())) {
|
//
|
||||||
String dlExternalNo = jsonArray.getJSONObject(0).getString("number");
|
// if (StringUtils.isBlank(result.getDlExternalNo())) {
|
||||||
result.setDlExternalNo(dlExternalNo);
|
// String dlExternalNo = jsonArray.getJSONObject(0).getString("number");
|
||||||
}
|
// result.setDlExternalNo(dlExternalNo);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// } else {
|
||||||
|
// log.warn("reservationId={} not found _embedded", eventData.getReservationId());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.logging.models;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Table(name="sys_booking_profile_mapping")
|
||||||
|
public class SysBookingProfileMapping {
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
@Column(name="category")
|
||||||
|
private String category;
|
||||||
|
@Column(name="player_id")
|
||||||
|
private String playerId;
|
||||||
|
@Column(name="profile_id")
|
||||||
|
private String profileId;
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.logging.repositories;
|
||||||
|
|
||||||
|
import com.mgm.mcrm.apigateway.logging.models.SysBookingProfileMapping;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface SysBookingProfileMappingDao extends JpaRepository<SysBookingProfileMapping, Long> {
|
||||||
|
List<SysBookingProfileMapping> findAllByCategoryAndPlayerId(String category, String playerId);
|
||||||
|
|
||||||
|
List<String> findByProfileId(String profileId);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.mgm.mcrm.apigateway.logging.services;
|
||||||
|
|
||||||
|
import com.mgm.mcrm.apigateway.logging.repositories.SysBookingProfileMappingDao;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SysBookingCacheService {
|
||||||
|
|
||||||
|
@Value("${mcrm.daylight.booking-search-cache-seconds}")
|
||||||
|
private int daylightCacheSeconds;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysBookingProfileMappingDao sysBookingProfileMappingDao;
|
||||||
|
|
||||||
|
public String getPlayerIdFromProfileId(String profileId) {
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(profileId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> result = sysBookingProfileMappingDao.findByProfileId(profileId);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(result)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.getFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,6 +105,8 @@ public class Bookings implements Serializable {
|
|||||||
private String mscRemark;
|
private String mscRemark;
|
||||||
@Column(name="approval_remark")
|
@Column(name="approval_remark")
|
||||||
private String approvalRemark;
|
private String approvalRemark;
|
||||||
|
@Column(name="approval_reason")
|
||||||
|
private String approvalReason;
|
||||||
@Column(name="room")
|
@Column(name="room")
|
||||||
private String room;
|
private String room;
|
||||||
@Column(name="sharer")
|
@Column(name="sharer")
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ public class BookingService {
|
|||||||
// book.setGuaranteeType("CGTD");
|
// book.setGuaranteeType("CGTD");
|
||||||
dbBooking.setPaymentType(null);
|
dbBooking.setPaymentType(null);
|
||||||
// book.setOperaProfileId(operaBooking.getOperaProfileId());
|
// book.setOperaProfileId(operaBooking.getOperaProfileId());
|
||||||
dbBooking.setApproveStatus("N");
|
dbBooking.setApproveStatus(daylightBooking.getApproveStatus());
|
||||||
dbBooking.setCategory("DAYLIGHT");
|
dbBooking.setCategory("DAYLIGHT");
|
||||||
|
|
||||||
dbBooking.setCreatedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
|
dbBooking.setCreatedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ mcrm:
|
|||||||
default-send-to: 201249946@qq.com
|
default-send-to: 201249946@qq.com
|
||||||
security:
|
security:
|
||||||
authorization-data: "[MCRM_APP/securItykeyOfCrmapp87895312],[MCRM_CMS/seCuritykeyOfCrmCms8wetw432]"
|
authorization-data: "[MCRM_APP/securItykeyOfCrmapp87895312],[MCRM_CMS/seCuritykeyOfCrmCms8wetw432]"
|
||||||
|
daylight:
|
||||||
|
booking-search-cache-seconds: 300
|
||||||
server:
|
server:
|
||||||
port: 9087
|
port: 9087
|
||||||
referrer-policy: origin-when-cross-origin
|
referrer-policy: origin-when-cross-origin
|
||||||
@@ -179,6 +181,8 @@ apns:
|
|||||||
|
|
||||||
daylight:
|
daylight:
|
||||||
scheduler:
|
scheduler:
|
||||||
|
# Enable startup fetches and scheduled tasks. Restart after changes.
|
||||||
|
open: false
|
||||||
# Cron fields: second minute hour day-of-month month day-of-week. Restart after changes.
|
# Cron fields: second minute hour day-of-month month day-of-week. Restart after changes.
|
||||||
configuration-cron: "0 0 2 * * ?"
|
configuration-cron: "0 0 2 * * ?"
|
||||||
configuration-zone: "Asia/Shanghai"
|
configuration-zone: "Asia/Shanghai"
|
||||||
|
|||||||
Reference in New Issue
Block a user