perf:江体小程序场地订阅优化

This commit is contained in:
Xiang
2026-03-23 10:25:54 +08:00
parent 7bf6b5d5ed
commit d40a15cbb5
5 changed files with 162 additions and 1 deletions

View File

@@ -0,0 +1,128 @@
package com.xiang.app.schedule.jntyzx;
import com.xiang.app.modules.jntyzx.constants.RedisKeyConstant;
import com.xiang.app.modules.jntyzx.entity.pojo.UserTokenInfoDO;
import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
import com.xiang.app.modules.jntyzx.entity.resp.query.SitePositionList;
import com.xiang.app.modules.jntyzx.service.IJntyzxHttpService;
import com.xiang.app.modules.jntyzx.service.IJtOrderService;
import com.xiang.app.modules.jntyzx.service.IUserTokenInfoService;
import com.xiang.app.modules.jntyzx.utils.VenueInfoUtils;
import com.xiang.app.modules.jntyzx.utils.WeekendUtils;
import com.xiang.core.quartz.annotation.XxzJob;
import com.xiang.xmc.service.cache.service.IRedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 江体小程序场地捡漏任务 周日和周二 启动捡漏周一和周三的场地
* @Author: xiang
* @Date: 2026-03-23 09:23
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class JtVenuePickTask {
private final IJntyzxHttpService jntyzxHttpService;
private final IUserTokenInfoService userTokenInfoService;
private final IRedisService redisService;
private final IJtOrderService jtOrderService;
@XxzJob(name = "jtVenuePickTask")
public void handler() {
log.info("江体小程序场地捡漏time:{}", System.currentTimeMillis());
List<UserTokenInfoDO> availableUser = userTokenInfoService.getAvailableUser();
if (CollectionUtils.isEmpty(availableUser)) {
log.info("当前无可用用户查询场地信息!");
return;
}
UserTokenInfoDO userTokenInfoDO = availableUser.get(0);
if (Objects.isNull(userTokenInfoDO)) {
return;
}
String subscribeKey = RedisKeyConstant.JNTYZX_ORDER_CREATE_KEY + userTokenInfoDO.getName() + LocalDate.now();
String subscribeValue = (String) redisService.get(subscribeKey);
if (StringUtils.isNotBlank(subscribeValue)) {
log.info("用户:{}今日已进行场地预定,不进行捡漏处理!", userTokenInfoDO.getName());
return;
}
String token = userTokenInfoDO.getToken();
List<SitePositionList> sitePositionLists = jntyzxHttpService.queryAvailableTomorrow(WeekendUtils.isWeekend(), token);
sitePositionLists = sitePositionLists.stream()
.filter(item -> !item.getPlaceName().contains("小馆"))
.filter(VenueInfoUtils::get8210VenueInfo)
.filter(item -> StringUtils.equals(item.getContacts(), "0")).toList();
if (CollectionUtils.isEmpty(sitePositionLists)) {
return;
}
Map<String, List<VenueInfoDO>> map = sitePositionLists.stream().map(item -> {
VenueInfoDO venueInfoDO = new VenueInfoDO();
venueInfoDO.setPlaceName(item.getPlaceName());
venueInfoDO.setPlaceId(item.getPlaceId());
venueInfoDO.setScheduleId(Integer.valueOf(item.getScheduleId()));
venueInfoDO.setSjName(item.getSjName());
venueInfoDO.setMoney(item.getMoney());
venueInfoDO.setClassName(item.getClassName());
venueInfoDO.setClassCode(item.getClassCode());
venueInfoDO.setAppointments(item.getAppointments());
venueInfoDO.setCTypeCode(item.getCtypeCode());
return venueInfoDO;
}).collect(Collectors.groupingByConcurrent(VenueInfoDO::getPlaceName));
if (MapUtils.isEmpty(map)) {
log.info("暂无可下单场地time:{}", System.currentTimeMillis());
return;
}
List<UserTokenInfoDO> users = userTokenInfoService.getCanOrderUser();
if (CollectionUtils.isEmpty(users)) {
log.info("暂无可下单用户, time:{}", System.currentTimeMillis());
return;
}
users.parallelStream().forEach(user -> {
try {
List<String> placeNameList = map.keySet().stream().sorted(Comparator.comparing(VenueInfoUtils::sortVenueInfo)).toList();
for (String placeName : placeNameList) {
List<VenueInfoDO> venueInfoDOList = map.get(placeName);
String valid = (String) redisService.get(RedisKeyConstant.getVenueSubscribeKey(placeName));
if (StringUtils.isNotBlank(valid)) {
break;
}
boolean order = jtOrderService.createOrder(venueInfoDOList, user);
if (order) {
return;
}
try {
Thread.sleep(1250);
} catch (InterruptedException e) {
log.error("睡眠失败~~~");
}
}
} catch (Exception e) {
// 关键点:异常只影响当前 user
log.error("createOrder 异常user={}", user.getId(), e);
return; // 结束这个 user不影响其他 user
}
});
}
}

View File

@@ -1,6 +1,7 @@
package com.xiang.app.schedule.jntyzx;
import com.xiang.app.common.service.dingtalk.JtDingTalkFactory;
import com.xiang.app.modules.jntyzx.constants.RedisKeyConstant;
import com.xiang.app.modules.jntyzx.entity.pojo.UserTokenInfoDO;
import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
import com.xiang.app.modules.jntyzx.service.IJtOrderService;
@@ -8,14 +9,17 @@ import com.xiang.app.modules.jntyzx.service.IUserTokenInfoService;
import com.xiang.app.modules.jntyzx.service.IVenueService;
import com.xiang.app.modules.jntyzx.utils.VenueInfoUtils;
import com.xiang.core.quartz.annotation.XxzJob;
import com.xiang.xmc.service.cache.service.IRedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -30,6 +34,7 @@ public class JtVenueSubscribeTask {
private final IJtOrderService jtOrderService;
private final IVenueService venueService;
private final JtDingTalkFactory jtDingTalkFactory;
private final IRedisService redisService;
@XxzJob(name = "jtVenueSubscribeTask")
@GetMapping("/jtVenueSubscribeTask")
@@ -51,9 +56,14 @@ public class JtVenueSubscribeTask {
users.parallelStream().forEach(user -> {
try {
for (String placeName : venueInfoMap.keySet()) {
List<String> placeNameList = venueInfoMap.keySet().stream().sorted(Comparator.comparing(VenueInfoUtils::sortVenueInfo)).toList();
for (String placeName : placeNameList) {
List<VenueInfoDO> venueInfoDOList = venueInfoMap.get(placeName);
for (int i = 0; i < 10; i++) {
String valid = (String) redisService.get(RedisKeyConstant.getVenueSubscribeKey(placeName));
if (StringUtils.isNotBlank(valid)) {
break;
}
boolean order = jtOrderService.createOrder(venueInfoDOList, user);
if (order) {
return;