package com.ruoyi.auction.service.impl;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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.AuctionBidRecord;
|
import com.ruoyi.auction.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>
|
* 拍卖商品表 服务实现类
|
* </p>
|
*
|
* @author mitao
|
* @since 2024-05-16
|
*/
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
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;
|
/**
|
* 获取拍卖商品列表的分页数据
|
*
|
* @param query 拍卖商品查询对象
|
* @return PageDTO<AuctionGoodsVO>
|
*/
|
@Override
|
public PageDTO<AuctionGoodsVO> getAuctionGoodsPage(AuctionGoodsQuery query) {
|
Set<Long> goodsSkuIdList = null;
|
if (StringUtils.isNotEmpty(query.getGoodsSkuName())) {
|
List<GoodsSku> goodsSku = goodsSkuClient.getGoodsByName(query.getGoodsSkuName(),
|
SecurityConstants.INNER)
|
.getData();
|
goodsSkuIdList = goodsSku.stream().map(GoodsSku::getId)
|
.collect(Collectors.toSet());
|
}
|
Page<AuctionGoods> page = this.lambdaQuery()
|
.select(AuctionGoods::getId, AuctionGoods::getGoodsSkuId,
|
AuctionGoods::getListingStatus, AuctionGoods::getStartStatus,
|
AuctionGoods::getStartTime, AuctionGoods::getEndTime,
|
AuctionGoods::getAuctionStock, AuctionGoods::getMinimumMarkupAmount).in(
|
StringUtils.isNotEmpty(goodsSkuIdList), AuctionGoods::getGoodsSkuId,
|
goodsSkuIdList).eq(StringUtils.isNotNull(query.getAuthentication()),
|
AuctionGoods::getAuthentication, query.getAuthentication())
|
.eq(StringUtils.isNotNull(query.getListingStatus()), AuctionGoods::getListingStatus,
|
query.getListingStatus())
|
.eq(StringUtils.isNotNull(query.getStartStatus()), AuctionGoods::getStartStatus,
|
query.getStartStatus())
|
.page(new Page<>(query.getPageCurr(), query.getPageSize()));
|
return PageDTO.of(page, AuctionGoodsVO.class);
|
}
|
|
@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, SecurityConstants.INNER)
|
.getData();
|
if (StringUtils.isNull(goodsSku)) {
|
throw new ServiceException("商品不存在");
|
}
|
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);
|
}
|
}
|
}
|
}
|