package com.izouma.nineth.service; import com.izouma.nineth.domain.*; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.enums.AssetStatus; import com.izouma.nineth.enums.OrderStatus; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.*; import com.izouma.nineth.utils.JpaUtils; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @Slf4j @Service @AllArgsConstructor public class ActivityOrderService { private ActivityOrderRepo activityOrderRepo; private ActivityCollectionRepo activityCollectionRepo; private ActivityCollectionService activityCollectionService; private AssetRepo assetRepo; private OrderRepo orderRepo; private CollectionRepo collectionRepo; private ActivityMaterialRepo activityMaterialRepo; private CollectionService collectionService; private AssetService assetService; private UserRepo userRepo; public Page all(PageQuery pageQuery) { return activityOrderRepo.findAll(JpaUtils.toSpecification(pageQuery, ActivityOrder.class), JpaUtils.toPageRequest(pageQuery)); } public Asset create(User user, Long mintActivityId) { try { ActivityCollection activity = activityCollectionRepo.findById(mintActivityId) .orElseThrow(new BusinessException("活动不存在")); //库存 int stock = Optional.ofNullable(activityCollectionService.increaseStock(mintActivityId, -1)) .map(Math::toIntExact) .orElseThrow(new BusinessException("很遗憾,活动已无库存")); if (stock < 0) { throw new BusinessException("活动已无库存"); } //数量 List assets = assetRepo.findAllByCollectionIdAndUserIdAndStatus(activity.getCollectionId(), user.getId(), AssetStatus.NORMAL); if (assets.size() < activity.getNum()) { throw new BusinessException("数量不足,无法领取"); } //兑换后的 Collection award = collectionRepo.findById(activity.getAwardCollectionId()) .orElseThrow(new BusinessException("无藏品")); int awardStock = Optional.ofNullable(collectionService.decreaseStock(activity.getAwardCollectionId(), 1)) .map(Math::toIntExact) .orElseThrow(new BusinessException("兑换藏品无库存")); if (awardStock < 0) { throw new BusinessException("兑换藏品无库存"); } //指定账户 User newOwner = userRepo.findByIdAndDelFalse(1590945L).orElseThrow(new BusinessException("无法兑换")); List consumption = assets.stream().limit(activity.getNum()).collect(Collectors.toList()); //消耗资产 consumption.forEach(asset -> { if (asset.isPublicShow()) { if (asset.getPublicCollectionId() != null) { List orders = orderRepo.findByCollectionId(asset.getPublicCollectionId()); if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) { throw new BusinessException("已有订单不可兑换"); } Collection collection = collectionRepo.findById(asset.getPublicCollectionId()) .orElseThrow(new BusinessException("无展示记录")); List collectionIds = collectionRepo.findAllByAssetId(collection.getAssetId()); if (CollectionUtils.isNotEmpty(collectionIds)) { log.info("删除collection {}", collectionIds); collectionRepo.deleteAllByIdIn(collectionIds); } else { log.info("删除collection {}", collection.getId()); collectionRepo.delete(collection); } } } }); //收集记录 ActivityOrder order = activityOrderRepo.save(ActivityOrder.builder() .userId(user.getId()) .phone(user.getPhone()) .activityCollection(activity.getCollectionName()) .activityCollectionId(mintActivityId) .build()); //兑换详情 consumption.forEach(asset -> { activityMaterialRepo.save( ActivityMaterial.builder() .orderId(order.getId()) .assetId(asset.getId()) .category(asset.getCategory()) .collectionId(asset.getCollectionId()) .name(asset.getName()) .number(asset.getNumber()) .pic(asset.getPic()) .build()); // 转赠 assetService.transfer(asset, asset.getPrice(), newOwner, "转赠", null); }); //发放新的 return assetService.createAsset(award, user, order.getId(), null, "兑换", award.getTotal() > 1 ? collectionService.getNextNumber(award.getId()) : null); } catch (Exception e) { // 错了加库存 activityCollectionService.increaseStock(mintActivityId, 1); throw e; } } }