| | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.auction.controller.management.dto.AuctionGoodsDTO; |
| | | import com.ruoyi.auction.controller.management.dto.AuctionGoodsQuery; |
| | | import com.ruoyi.auction.controller.management.vo.AuctionBidRecordVO; |
| | | import com.ruoyi.auction.controller.management.vo.AuctionGoodsVO; |
| | | import com.ruoyi.auction.domain.AuctionGoods; |
| | | import com.ruoyi.auction.domain.AuctionBidRecord; |
| | | import com.ruoyi.system.api.domain.AuctionGoods; |
| | | import com.ruoyi.auction.mapper.AuctionGoodsMapper; |
| | | import com.ruoyi.auction.service.IAuctionBidRecordService; |
| | | import com.ruoyi.auction.service.IAuctionGoodsService; |
| | | import com.ruoyi.common.core.constant.SecurityConstants; |
| | | import com.ruoyi.common.core.enums.AuctionOrderTypeEnum; |
| | | import com.ruoyi.common.core.enums.AuctionStartStatusEnum; |
| | | import com.ruoyi.common.core.enums.BidStatusEnum; |
| | | import com.ruoyi.common.core.enums.BondStatusEnum; |
| | | import com.ruoyi.common.core.enums.OrderFromEnum; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.page.BeanUtils; |
| | | import com.ruoyi.common.core.utils.page.PageDTO; |
| | | import com.ruoyi.system.api.domain.GoodsSku; |
| | | import com.ruoyi.system.api.domain.Member; |
| | | import com.ruoyi.system.api.domain.MemberAddress; |
| | | import com.ruoyi.system.api.domain.OrderAuctionBond; |
| | | import com.ruoyi.system.api.domain.dto.OrderDTO; |
| | | import com.ruoyi.system.api.domain.dto.RefundDTO; |
| | | import com.ruoyi.system.api.feignClient.GoodsSkuClient; |
| | | import com.ruoyi.system.api.feignClient.MemberClient; |
| | | import com.ruoyi.system.api.feignClient.OrderClient; |
| | | import io.seata.spring.annotation.GlobalTransactional; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | public class AuctionGoodsServiceImpl extends ServiceImpl<AuctionGoodsMapper, AuctionGoods> implements IAuctionGoodsService { |
| | | |
| | | private final GoodsSkuClient goodsSkuClient; |
| | | |
| | | private final MemberClient memberClient; |
| | | private final OrderClient orderClient; |
| | | private final IAuctionBidRecordService auctionBidRecordService; |
| | | /** |
| | | * 获取拍卖商品列表的分页数据 |
| | | * |
| | |
| | | public PageDTO<AuctionGoodsVO> getAuctionGoodsPage(AuctionGoodsQuery query) { |
| | | Set<Long> goodsSkuIdList = null; |
| | | if (StringUtils.isNotEmpty(query.getGoodsSkuName())) { |
| | | List<GoodsSku> goodsSku = goodsSkuClient.getGoodsByName(query.getGoodsSkuName()) |
| | | List<GoodsSku> goodsSku = goodsSkuClient.getGoodsByName(query.getGoodsSkuName(), |
| | | SecurityConstants.INNER) |
| | | .getData(); |
| | | goodsSkuIdList = goodsSku.stream().map(GoodsSku::getId) |
| | | .collect(Collectors.toSet()); |
| | |
| | | } |
| | | |
| | | @Override |
| | | @GlobalTransactional(rollbackFor = Exception.class) |
| | | @Transactional |
| | | public void saveAuctionGoods(AuctionGoodsDTO dto) { |
| | | Long id = dto.getId(); |
| | | Long goodsSkuId = dto.getGoodsSkuId(); |
| | | AuctionGoods auctionGoods = BeanUtils.copyBean(dto, AuctionGoods.class); |
| | | // 添加 |
| | | if (StringUtils.isNull(id)) { |
| | | if (StringUtils.isNull(goodsSkuId)) { |
| | | throw new ServiceException("商品id不能为空"); |
| | | } |
| | | GoodsSku goodsSku = goodsSkuClient.getGoodsSkuOne(goodsSkuId).getData(); |
| | | GoodsSku goodsSku = goodsSkuClient.getGoodsSkuOne(goodsSkuId, SecurityConstants.INNER) |
| | | .getData(); |
| | | if (StringUtils.isNull(goodsSku)) { |
| | | throw new ServiceException("商品不存在"); |
| | | } |
| | | AuctionGoods auctionGoods = BeanUtils.copyBean(dto, AuctionGoods.class); |
| | | if (goodsSku.getStock() < dto.getAuctionStock()) { |
| | | throw new ServiceException("商品库存不足"); |
| | | } |
| | | this.save(auctionGoods); |
| | | |
| | | // 扣减商品库存 |
| | | goodsSkuClient.deductStock(goodsSkuId, dto.getAuctionStock(), SecurityConstants.INNER); |
| | | } else { |
| | | // 编辑 |
| | | AuctionGoods auctionGoodsOrg = this.getById(id); |
| | | if (StringUtils.isNull(auctionGoodsOrg)) { |
| | | throw new ServiceException("拍卖商品不存在"); |
| | | } |
| | | if (auctionGoodsOrg.getStartStatus().equals(AuctionStartStatusEnum.IN_AUCTION)) { |
| | | throw new ServiceException("该商品正在拍卖中,不能修改"); |
| | | } |
| | | GoodsSku goodsSku = goodsSkuClient.getGoodsSkuOne(goodsSkuId, SecurityConstants.INNER) |
| | | .getData(); |
| | | if (StringUtils.isNull(goodsSku)) { |
| | | throw new ServiceException("商品不存在"); |
| | | } |
| | | if (goodsSku.getStock() + auctionGoodsOrg.getAuctionStock() < dto.getAuctionStock()) { |
| | | throw new ServiceException("商品库存不足"); |
| | | } |
| | | // 编辑商品时需要先回退商品库存,再扣减最新的商品库存 |
| | | goodsSkuClient.returningStock(auctionGoodsOrg.getGoodsSkuId(), |
| | | auctionGoodsOrg.getAuctionStock(), SecurityConstants.INNER); |
| | | auctionGoodsOrg.setStartingPrice(dto.getStartingPrice()); |
| | | auctionGoodsOrg.setMinimumMarkupAmount(dto.getMinimumMarkupAmount()); |
| | | auctionGoodsOrg.setStartTime(dto.getStartTime()); |
| | | auctionGoodsOrg.setEndTime(dto.getEndTime()); |
| | | auctionGoodsOrg.setAuctionStock(dto.getAuctionStock()); |
| | | auctionGoodsOrg.setBond(dto.getBond()); |
| | | auctionGoodsOrg.setAuthentication(dto.getAuthentication()); |
| | | auctionGoodsOrg.setDescription(dto.getDescription()); |
| | | auctionGoodsOrg.setShareTitle(dto.getShareTitle()); |
| | | auctionGoodsOrg.setSharePic(dto.getSharePic()); |
| | | this.updateById(auctionGoodsOrg); |
| | | // 扣减库存 |
| | | goodsSkuClient.deductStock(auctionGoodsOrg.getGoodsSkuId(), |
| | | auctionGoodsOrg.getAuctionStock(), SecurityConstants.INNER); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 查看拍卖商品详情 |
| | | * |
| | | * @param id 拍卖商品id |
| | | * @return AuctionGoodsVO |
| | | */ |
| | | @Override |
| | | public AuctionGoodsVO getAuctionGoodsById(Long id) { |
| | | AuctionGoods auctionGoods = this.getById(id); |
| | | if (StringUtils.isNull(auctionGoods)) { |
| | | throw new ServiceException("拍卖商品不存在"); |
| | | } |
| | | AuctionGoodsVO auctionGoodsVO = BeanUtils.copyBean(auctionGoods, AuctionGoodsVO.class); |
| | | if (!auctionGoods.getStartStatus().equals(AuctionStartStatusEnum.IN_PREVIEW)) { |
| | | List<AuctionBidRecord> list = auctionBidRecordService.lambdaQuery() |
| | | .eq(AuctionBidRecord::getTargetId, auctionGoodsVO.getId()) |
| | | .eq(AuctionBidRecord::getAuctionType, AuctionOrderTypeEnum.REGULAR_ITEMS) |
| | | .orderByDesc(AuctionBidRecord::getLastBidAmount).list(); |
| | | if (StringUtils.isNotEmpty(list)) { |
| | | Set<Long> collect = list.stream().map(AuctionBidRecord::getMemberId) |
| | | .collect(Collectors.toSet()); |
| | | List<Member> memberList = memberClient. |
| | | getMemberListByIds(collect, SecurityConstants.INNER).getData(); |
| | | Map<Long, String> memberMap = memberList.stream() |
| | | .collect(Collectors.toMap(Member::getId, Member::getNickname)); |
| | | List<AuctionBidRecordVO> auctionBidRecordVOS = BeanUtils.copyList(list, |
| | | AuctionBidRecordVO.class); |
| | | for (AuctionBidRecordVO vo : auctionBidRecordVOS) { |
| | | String memberName = memberMap.get(vo.getMemberId()); |
| | | vo.setMemberName(StringUtils.isNotEmpty(memberName) ? memberName : ""); |
| | | } |
| | | auctionGoodsVO.setRecordList(auctionBidRecordVOS); |
| | | } |
| | | } |
| | | return auctionGoodsVO; |
| | | } |
| | | |
| | | /** |
| | | * 立即结束 |
| | | * |
| | | * @param id 拍卖商品id |
| | | */ |
| | | @Override |
| | | @GlobalTransactional(rollbackFor = Exception.class) |
| | | @Transactional |
| | | public void stopAuctionGoods(Long id) { |
| | | AuctionGoods auctionGoods = this.lambdaQuery().eq(AuctionGoods::getId, id) |
| | | .eq(AuctionGoods::getStartStatus, AuctionStartStatusEnum.IN_AUCTION).one(); |
| | | if (StringUtils.isNull(auctionGoods)) { |
| | | throw new ServiceException("拍卖商品不存在"); |
| | | } |
| | | if (auctionGoods.getStartStatus().equals(AuctionStartStatusEnum.IN_AUCTION)) { |
| | | // 查询出价记录 |
| | | List<AuctionBidRecord> auctionBidRecords = auctionBidRecordService.getBidRecordByGoodsId( |
| | | id); |
| | | Long memberId = null; |
| | | if (StringUtils.isNotEmpty(auctionBidRecords)) { |
| | | // 中标 |
| | | AuctionBidRecord auctionBidRecord = auctionBidRecords.get(0); |
| | | auctionBidRecord.setStatus(BidStatusEnum.SUCCESSFUL); |
| | | auctionBidRecordService.updateById(auctionBidRecord); |
| | | memberId = auctionBidRecord.getMemberId(); |
| | | // 创建待支付订单 |
| | | OrderDTO orderDTO = new OrderDTO(); |
| | | orderDTO.setAuctionType(AuctionOrderTypeEnum.REGULAR_ITEMS); |
| | | orderDTO.setGoodsQuantity(auctionGoods.getAuctionStock()); |
| | | orderDTO.setGoodsSkuId(auctionGoods.getGoodsSkuId()); |
| | | orderDTO.setBound(auctionGoods.getBond()); |
| | | orderDTO.setMemberId(auctionBidRecord.getMemberId()); |
| | | orderDTO.setTotalAmount(auctionBidRecord.getLastBidAmount()); |
| | | orderDTO.setOrderFrom(OrderFromEnum.AUCTION_ORDERS); |
| | | orderDTO.setOrderTime(LocalDateTime.now()); |
| | | MemberAddress data = memberClient.getMemberAddressOne( |
| | | auctionBidRecord.getMemberId(), SecurityConstants.INNER).getData(); |
| | | if (StringUtils.isNotNull(data)) { |
| | | orderDTO.setReceiverName(data.getRecipientName()); |
| | | orderDTO.setReceiverCity(data.getReceiverCity()); |
| | | orderDTO.setReceiverDetailAddress(data.getDetailedAddress()); |
| | | orderDTO.setReceiverphone(data.getRecipientPhone()); |
| | | } |
| | | orderClient.saveOrderOne(orderDTO, SecurityConstants.INNER); |
| | | } else { |
| | | // 没有人出价,退回拍卖商品库存 |
| | | goodsSkuClient.returningStock(auctionGoods.getGoodsSkuId(), |
| | | auctionGoods.getAuctionStock(), SecurityConstants.INNER); |
| | | } |
| | | // 结束拍卖 |
| | | this.lambdaUpdate().set(AuctionGoods::getStartStatus, AuctionStartStatusEnum.ENDED) |
| | | .eq(AuctionGoods::getId, id).update(); |
| | | // 查询已支付保证金记录 |
| | | List<OrderAuctionBond> auctionBondList = orderClient.getOrderAuctionBondList(id, |
| | | AuctionOrderTypeEnum.REGULAR_ITEMS, |
| | | BondStatusEnum.PAID, |
| | | SecurityConstants.INNER).getData(); |
| | | if (StringUtils.isNotEmpty(auctionBondList)) { |
| | | List<RefundDTO> refundDTOList = new ArrayList<>(); |
| | | for (OrderAuctionBond orderAuctionBond : auctionBondList) { |
| | | // 已中标需在订单完成后退保证金 |
| | | if (orderAuctionBond.getMemberId().equals(memberId)) { |
| | | continue; |
| | | } |
| | | RefundDTO refundDTO = new RefundDTO(); |
| | | refundDTO.setOrderNo(orderAuctionBond.getOrderNo()); |
| | | refundDTO.setAmount(orderAuctionBond.getBond()); |
| | | } |
| | | // 远程调用订单服务进行退款 |
| | | Map<String, Object> data = orderClient.refund(refundDTOList, |
| | | SecurityConstants.INNER).getData(); |
| | | // 处理退款返回结果 |
| | | List<String> successfulOrders = new ArrayList<>(); |
| | | List<String> failedOrders = new ArrayList<>(); |
| | | |
| | | data.forEach((key, value) -> { |
| | | if ((boolean) value) { |
| | | successfulOrders.add(key); |
| | | } else { |
| | | failedOrders.add(key); |
| | | } |
| | | }); |
| | | log.info("订单号:{},退款失败", failedOrders); |
| | | // 退款成功的订单修改状态 |
| | | List<Long> ids = auctionBondList.stream().map(bond -> { |
| | | if (successfulOrders.contains(bond.getOrderNo())) { |
| | | return bond.getId(); |
| | | } |
| | | return null; |
| | | }).filter(Objects::nonNull).collect(Collectors.toList()); |
| | | // 远程调用订单服务修改订单状态 |
| | | orderClient.updateOrderAuctionBondStatus(ids, BondStatusEnum.PAID); |
| | | } |
| | | } |
| | | } |
| | | } |