|
@@ -31,6 +31,8 @@ import com.tourism.webadmin.back.service.TourProjectGroupPurchaseService;
|
|
import com.tourism.webadmin.back.service.TourismProjectService;
|
|
import com.tourism.webadmin.back.service.TourismProjectService;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.redisson.api.RLock;
|
|
|
|
+import org.redisson.api.RedissonClient;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -39,6 +41,7 @@ import java.math.BigDecimal;
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -63,7 +66,10 @@ public class TourProjectGroupPurchaseServiceImpl extends BaseService<TourProject
|
|
private TourOrderService tourOrderService;
|
|
private TourOrderService tourOrderService;
|
|
@Autowired
|
|
@Autowired
|
|
private MergeAvatarsFlexUtils mergeAvatarsFlexUtils;
|
|
private MergeAvatarsFlexUtils mergeAvatarsFlexUtils;
|
|
|
|
+ @Autowired
|
|
private TourUserServiceImpl tourUserService;
|
|
private TourUserServiceImpl tourUserService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedissonClient redissonClient;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 返回当前Service的主表Mapper对象。
|
|
* 返回当前Service的主表Mapper对象。
|
|
@@ -186,61 +192,81 @@ public class TourProjectGroupPurchaseServiceImpl extends BaseService<TourProject
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public TourProjectGroupPurchase handleGroupBuy(TourismBookProjectDto paramDTO, TourOrder tourOrder){
|
|
public TourProjectGroupPurchase handleGroupBuy(TourismBookProjectDto paramDTO, TourOrder tourOrder){
|
|
- TourProjectGroupPurchase groupPurchase = this.getById(paramDTO.getGroupId());
|
|
|
|
- if (groupPurchase != null) {
|
|
|
|
- // 先判断下拼团信息是不是过期了 由于这里默认是yyyy-MM-dd 00:00:00 所以要加一天
|
|
|
|
- Date newDate = MyDateUtil.addDays(groupPurchase.getEndTime(), 1);
|
|
|
|
- if (newDate.getTime() < System.currentTimeMillis()) {
|
|
|
|
- throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_HAS_EXPIRED.getErrorMessage());
|
|
|
|
|
|
+ TourProjectGroupPurchase groupPurchase = null;
|
|
|
|
+ // 增加redis并发锁
|
|
|
|
+ String lockKey = "group_buying:" + paramDTO.getGroupId();
|
|
|
|
+ RLock lock = null;
|
|
|
|
+ try {
|
|
|
|
+ lock = redissonClient.getLock(lockKey);
|
|
|
|
+ lock.lock(5, TimeUnit.SECONDS);
|
|
|
|
+ // 由于redisson的锁是一次性的,所以这里可以不用判断锁是否获取成功
|
|
|
|
+ log.info("redisson<=======================================>{}",lockKey);
|
|
|
|
+
|
|
|
|
+ groupPurchase = this.getById(paramDTO.getGroupId());
|
|
|
|
+ if (groupPurchase != null) {
|
|
|
|
+ // 先判断下拼团信息是不是过期了 由于这里默认是yyyy-MM-dd 00:00:00 所以要加一天
|
|
|
|
+ Date newDate = MyDateUtil.addDays(groupPurchase.getEndTime(), 1);
|
|
|
|
+ if (newDate.getTime() < System.currentTimeMillis()) {
|
|
|
|
+ throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_HAS_EXPIRED.getErrorMessage());
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_DOES_NOT_EXIST.getErrorMessage());
|
|
}
|
|
}
|
|
- }else {
|
|
|
|
- throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_DOES_NOT_EXIST.getErrorMessage());
|
|
|
|
- }
|
|
|
|
- // 计算此次订单参加拼团人数
|
|
|
|
- Integer groupCount = paramDTO.getAdultNumber() + paramDTO.getChildrenNumber();
|
|
|
|
- if(groupCount > groupPurchase.getMaxCount()){
|
|
|
|
- throw new MyRuntimeException(ErrorCodeEnum.PEOPLE_EXCCEDS.getErrorMessage());
|
|
|
|
- }
|
|
|
|
- // 获取已参团的用户头像信息并拼接头像,放到团购信息里
|
|
|
|
- String usersAvatars = groupPurchase.getUsersAvatars();
|
|
|
|
- if(StringUtils.isNotBlank(usersAvatars)){
|
|
|
|
- groupPurchase.setUsersAvatars(usersAvatars + "," + TokenData.takeFromRequest().getHeadImageUrl());
|
|
|
|
- }else {
|
|
|
|
- String url = TokenData.takeFromRequest().getHeadImageUrl();
|
|
|
|
- if(StringUtils.isBlank(TokenData.takeFromRequest().getHeadImageUrl())){
|
|
|
|
- url = tourUserService.getById(TokenData.takeFromRequest().getUserId()).getHeadImageUrl();
|
|
|
|
|
|
+ // 计算此次订单参加拼团人数
|
|
|
|
+ Integer groupCount = paramDTO.getAdultNumber() + paramDTO.getChildrenNumber();
|
|
|
|
+ if (groupCount > groupPurchase.getMaxCount()) {
|
|
|
|
+ throw new MyRuntimeException(ErrorCodeEnum.PEOPLE_EXCCEDS.getErrorMessage());
|
|
|
|
+ }
|
|
|
|
+ // 获取已参团的用户头像信息并拼接头像,放到团购信息里
|
|
|
|
+ String usersAvatars = groupPurchase.getUsersAvatars();
|
|
|
|
+ if (StringUtils.isNotBlank(usersAvatars)) {
|
|
|
|
+ groupPurchase.setUsersAvatars(usersAvatars + "," + TokenData.takeFromRequest().getHeadImageUrl());
|
|
|
|
+ } else {
|
|
|
|
+ String url = TokenData.takeFromRequest().getHeadImageUrl();
|
|
|
|
+ if (StringUtils.isBlank(TokenData.takeFromRequest().getHeadImageUrl())) {
|
|
|
|
+ url = tourUserService.getById(TokenData.takeFromRequest().getUserId()).getHeadImageUrl();
|
|
|
|
+ }
|
|
|
|
+ groupPurchase.setUsersAvatars(url);
|
|
|
|
+ }
|
|
|
|
+ // usersAvatars用,分割成List
|
|
|
|
+ if (StringUtils.isNotBlank(usersAvatars)) {
|
|
|
|
+ List<String> headImageUrlList = Arrays.asList(usersAvatars.split(","));
|
|
|
|
+ // 去掉list里的null字符串
|
|
|
|
+ headImageUrlList = headImageUrlList.stream().filter(e -> !"null".equals(e)).collect(Collectors.toList());
|
|
|
|
+ groupPurchase.setSplicingAvatars(this.splicingAvatars(headImageUrlList));
|
|
}
|
|
}
|
|
- groupPurchase.setUsersAvatars(url);
|
|
|
|
- }
|
|
|
|
- // usersAvatars用,分割成List
|
|
|
|
- if(StringUtils.isNotBlank(usersAvatars)) {
|
|
|
|
- List<String> headImageUrlList = Arrays.asList(usersAvatars.split(","));
|
|
|
|
- // 去掉list里的null字符串
|
|
|
|
- headImageUrlList = headImageUrlList.stream().filter(e->!"null".equals(e)).collect(Collectors.toList());
|
|
|
|
- groupPurchase.setSplicingAvatars(this.splicingAvatars(headImageUrlList));
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if(groupPurchase.getNowCount() == 0) {
|
|
|
|
- tourOrder.setTeamLeader(1);
|
|
|
|
- }
|
|
|
|
|
|
+ if (groupPurchase.getNowCount() == 0) {
|
|
|
|
+ tourOrder.setTeamLeader(1);
|
|
|
|
+ }
|
|
|
|
|
|
- // 2024-01-08逻辑修改 // 判断人数是不是超了,如果超了或者人数满了,自动开个完全一样的新团,直接在新团上加数量
|
|
|
|
- // 如果超过团购人数,则需要提醒已经满团,不允许客户继续参团
|
|
|
|
- if(groupCount + groupPurchase.getNowCount() > groupPurchase.getMaxCount()) {
|
|
|
|
- throw new MyRuntimeException(ErrorCodeEnum.FULL_GROUP_ERROR.getErrorMessage());
|
|
|
|
- } else if (groupCount + groupPurchase.getNowCount() == groupPurchase.getMaxCount()) {
|
|
|
|
- groupPurchase.setNowCount(groupCount + groupPurchase.getNowCount());
|
|
|
|
- groupPurchase.setSuccess(1);
|
|
|
|
- groupPurchase.setNowPrice(groupPurchase.getAdultPrice());
|
|
|
|
- groupPurchase.setNextPrice(groupPurchase.getAdultPrice());
|
|
|
|
- groupPurchase.setNextStageNum(0);
|
|
|
|
- groupPurchase = tourProjectGroupPurchaseDetailService.getNowPriceAndNextStagePrice(groupPurchase);
|
|
|
|
- this.updateById(groupPurchase);
|
|
|
|
- }else {
|
|
|
|
- groupPurchase.setNowCount(groupCount + groupPurchase.getNowCount());
|
|
|
|
- // 拼团后修改团购的当前价格、下阶段价格、距离下阶段人数
|
|
|
|
- groupPurchase = tourProjectGroupPurchaseDetailService.getNowPriceAndNextStagePrice(groupPurchase);
|
|
|
|
- this.updateById(groupPurchase);
|
|
|
|
|
|
+ // 2024-01-08逻辑修改 // 判断人数是不是超了,如果超了或者人数满了,自动开个完全一样的新团,直接在新团上加数量
|
|
|
|
+ // 如果超过团购人数,则需要提醒已经满团,不允许客户继续参团
|
|
|
|
+ if (groupCount + groupPurchase.getNowCount() > groupPurchase.getMaxCount()) {
|
|
|
|
+ throw new MyRuntimeException(ErrorCodeEnum.FULL_GROUP_ERROR.getErrorMessage());
|
|
|
|
+ } else if (groupCount + groupPurchase.getNowCount() == groupPurchase.getMaxCount()) {
|
|
|
|
+ groupPurchase.setNowCount(groupCount + groupPurchase.getNowCount());
|
|
|
|
+ groupPurchase.setSuccess(1);
|
|
|
|
+ groupPurchase.setNowPrice(groupPurchase.getAdultPrice());
|
|
|
|
+ groupPurchase.setNextPrice(groupPurchase.getAdultPrice());
|
|
|
|
+ groupPurchase.setNextStageNum(0);
|
|
|
|
+ groupPurchase = tourProjectGroupPurchaseDetailService.getNowPriceAndNextStagePrice(groupPurchase);
|
|
|
|
+ this.updateById(groupPurchase);
|
|
|
|
+ } else {
|
|
|
|
+ groupPurchase.setNowCount(groupCount + groupPurchase.getNowCount());
|
|
|
|
+ // 拼团后修改团购的当前价格、下阶段价格、距离下阶段人数
|
|
|
|
+ groupPurchase = tourProjectGroupPurchaseDetailService.getNowPriceAndNextStagePrice(groupPurchase);
|
|
|
|
+ this.updateById(groupPurchase);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_ERROR.getErrorMessage());
|
|
|
|
+ }finally {
|
|
|
|
+ // 检查锁是否释放,如果未释放,释放锁
|
|
|
|
+ if (lock != null && !lock.isLocked()) {
|
|
|
|
+ lock.unlock();
|
|
|
|
+ log.info("redisson锁<=======================================>解锁成功");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
tourOrder.setType(1);
|
|
tourOrder.setType(1);
|
|
// 计算订单价格
|
|
// 计算订单价格
|