更新了服务类订单模块

This commit is contained in:
chen-xin-zhi 2025-02-12 11:50:54 +08:00
parent 20278363e4
commit dc1d3913c4
20 changed files with 552 additions and 216 deletions

View File

@ -21,4 +21,6 @@ public interface OrderStatusConstant {
String PAYMENT_REFUNDED = "已退款";
}

View File

@ -1,7 +1,6 @@
package com.cultural.heritage.controller.good;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cultural.heritage.common.BaseResponse;
import com.cultural.heritage.common.ErrorCode;
@ -12,14 +11,14 @@ import com.cultural.heritage.model.dto.CommonBatchRequest;
import com.cultural.heritage.model.dto.cartService.CartExperienceAddRequest;
import com.cultural.heritage.model.dto.cartService.CartExperienceUpdateRequest;
import com.cultural.heritage.model.dto.order.BuySingleServiceGoodVerifyRequest;
import com.cultural.heritage.model.entity.CartExperience;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceOrderVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceVO;
import com.cultural.heritage.service.common.CommonService;
import com.cultural.heritage.service.good.CartExperienceService;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.service.user.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -55,6 +54,15 @@ public class CartExperienceController {
private UserService userService;
@Resource
private CommonService commonService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/**
* 小程序端用户添加服务类商品至购物车
@ -86,11 +94,8 @@ public class CartExperienceController {
}
userService.getLoginUser(request);
// 获取购物车id列表
List<Long> cartIds = cartExperienceUpdateRequestList.stream().map(CartExperienceUpdateRequest::getId).toList();
QueryWrapper<CartExperience> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartIds);
List<CartExperience> cartExperienceList = cartExperienceService.list(queryWrapper);
// 获取服务类购物车商品列表
List<CartExperience> cartExperienceList = commonService.getItemsByIds(cartExperienceUpdateRequestList, cartExperienceService, CartExperienceUpdateRequest::getId);
// 封装map集合购物车id, 商品数量
Map<Long, Integer> QuantityMap = new HashMap<>();
@ -108,11 +113,8 @@ public class CartExperienceController {
timeSlotMap.put(id, timeSlot);
}
// 获取商品id列表
List<Long> goodIds = cartExperienceList.stream().map(CartExperience::getGoodId).toList();
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(goodQueryWrapper);
// 获取商品列表
List<Good> goodList = commonService.getItemsByIds(cartExperienceList, goodService, CartExperience::getGoodId);
// 封装map集合商品id, 商品价格
Map<Long, BigDecimal> priceMap = new HashMap<>();
@ -219,18 +221,11 @@ public class CartExperienceController {
}
userService.getLoginUser(request);
List<Long> cartExperienceIds = commonBatchRequest.getIdList();
List<CartExperience> cartExperienceList = cartExperienceService.list();
// 获取购物车列表信息
List<CartExperience> cartExperiences = cartExperienceList.stream().filter(cartExperience -> {
Long id = cartExperience.getId();
return cartExperienceIds.contains(id);
}).toList();
// 获取购物车信息列表
List<CartExperience> cartExperiences = commonService.getListByIds(cartExperienceIds, cartExperienceService);
// 提取出购物车中的商品id列表
List<Long> goodIds = cartExperiences.stream().map(CartExperience::getGoodId).toList();
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 获取购物车中的商品列表
List<Good> goodList = commonService.getItemsByIds(cartExperiences, goodService, CartExperience::getGoodId);
// 封装goodMap(根据商品id查询商品)
Map<Long, Good> goodMap = new HashMap<>();
@ -238,6 +233,22 @@ public class CartExperienceController {
goodMap.put(good.getId(), good);
}
// 校验购物车商品
Map<String, PendingServiceGood> pendingServiceGoodMap = goodService.getPendingServiceGoodMap();
List<PendingServiceOrder> pendingServiceOrderList = pendingServiceOrderService.list();
for (CartExperience cartExperience : cartExperiences) {
Long goodId = cartExperience.getGoodId();
String reservationDate = cartExperience.getReservationDate();
String timeSlot = cartExperience.getTimeSlot();
Integer quantity = cartExperience.getQuantity();
Good good = goodMap.get(goodId);
// 判断商品是否存在或者下架
goodService.checkGoodIsExist(good);
// 校验购买的服务类购物车中的商品预约情况是否合理
goodService.checkServiceGoodCartBookingDetailIsProperly(goodId, reservationDate, timeSlot, quantity, pendingServiceGoodMap, pendingServiceOrderList);
}
// 封装提交订单页的商品信息列表
List<CartExperienceOrderVO> cartOrderVOList = new ArrayList<>();
for (CartExperience cartExperience : cartExperiences) {
@ -276,22 +287,16 @@ public class CartExperienceController {
}
userService.getLoginUser(request);
Long goodId = buySingleServiceGoodVerifyRequest.getGoodId();
// 校验商品是否存在或者下架
Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.SYSTEM_ERROR, "商品已下架或不存在");
goodService.checkGoodIsExist(good);
String reservationDate = buySingleServiceGoodVerifyRequest.getReservationDate();
String timeSlot = buySingleServiceGoodVerifyRequest.getTimeSlot();
Integer quantity = buySingleServiceGoodVerifyRequest.getQuantity();
String startTime = timeSlot.split("-")[0];
String advanceDateTimeStr = reservationDate + " " + startTime + ":00";
String currentDateTimeStr = DateUtil.now();
Date advanceDateTime = DateUtil.parse(advanceDateTimeStr, "yyyy-MM-dd HH:mm:ss");
Date currentDateTime = DateUtil.parse(currentDateTimeStr, "yyyy-MM-dd HH:mm:ss");
int result = DateUtil.compare(advanceDateTime, currentDateTime);
ThrowUtils.throwIf(result <= 0, ErrorCode.OPERATION_ERROR, "当前时间段已过期");
// 校验购买的服务类商品预约情况是否合理
goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, quantity);
return ResultUtils.success(true);
}

View File

@ -16,6 +16,7 @@ import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.vo.cart.CartGoodVO;
import com.cultural.heritage.model.vo.cart.CartOrderVO;
import com.cultural.heritage.model.vo.cart.CartRecordVO;
import com.cultural.heritage.service.common.CommonService;
import com.cultural.heritage.service.good.CartRecordService;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.user.UserService;
@ -41,6 +42,10 @@ import java.util.*;
public class CartRecordController {
@Resource
private CommonService commonService;
@Resource
private CartRecordService cartRecordService;
@ -82,25 +87,17 @@ public class CartRecordController {
}
userService.getLoginUser(request);
// 获取购物车id列表
List<Long> cartIds = cartRecordUpdateRequestList.stream().map(CartRecordUpdateRequest::getId).toList();
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartIds);
List<CartRecord> cartRecordList = cartRecordService.list(queryWrapper);
// 获取购物车列表
List<CartRecord> cartRecordList = commonService.getItemsByIds(cartRecordUpdateRequestList, cartRecordService, CartRecordUpdateRequest::getId);
// 封装map集合购物车id, 商品数量
Map<Long, Integer> QuantityMap = new HashMap<>();
for (CartRecordUpdateRequest cartRecordUpdateRequest : cartRecordUpdateRequestList) {
Long id = cartRecordUpdateRequest.getId();
Integer quantity = cartRecordUpdateRequest.getQuantity();
QuantityMap.put(id, quantity);
QuantityMap.put(cartRecordUpdateRequest.getId(), cartRecordUpdateRequest.getQuantity());
}
// 获取商品id列表
List<Long> goodIds = cartRecordList.stream().map(CartRecord::getGoodId).toList();
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(goodQueryWrapper);
// 获取商品列表
List<Good> goodList = commonService.getItemsByIds(cartRecordList, goodService, CartRecord::getGoodId);
// 封装map集合商品id, 商品价格
Map<Long, BigDecimal> priceMap = new HashMap<>();
@ -134,7 +131,7 @@ public class CartRecordController {
@PostMapping("/delete")
@Operation(summary = "小程序端用户删除常规类购物车中的物品", description = "参数:购物车记录删除请求体(商品id列表如[2,3,4])权限所有人方法名deleteCart")
public BaseResponse<Boolean> deleteCart(@RequestBody CommonBatchRequest commonBatchRequest, HttpServletRequest request) {
if (commonBatchRequest == null || commonBatchRequest.getIdList().isEmpty()) {
if (commonBatchRequest == null || CollectionUtils.isEmpty(commonBatchRequest.getIdList())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
userService.getLoginUser(request);
@ -197,29 +194,29 @@ public class CartRecordController {
@PostMapping("/submit/list")
@Operation(summary = "小程序端显示常规类购物车提交订单页的商品信息", description = "参数:购物车id列表权限所有人方法名listCartRecord")
public BaseResponse<List<CartOrderVO>> listCartRecord(@RequestBody CommonBatchRequest commonBatchRequest, HttpServletRequest request) {
if (commonBatchRequest == null || commonBatchRequest.getIdList().isEmpty()) {
if (commonBatchRequest == null || CollectionUtils.isEmpty(commonBatchRequest.getIdList())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
userService.getLoginUser(request);
List<Long> cartRecordIds = commonBatchRequest.getIdList();
List<CartRecord> cartRecordList = cartRecordService.list();
// 获取购物车列表信息
List<CartRecord> cartRecords = cartRecordList.stream().filter(cartRecord -> {
Long id = cartRecord.getId();
return cartRecordIds.contains(id);
}).toList();
// 根据id列表获取购物车信息列表
List<CartRecord> cartRecords = commonService.getListByIds(cartRecordIds, cartRecordService);
// 提取出购物车中的商品id列表
List<Long> goodIds = cartRecords.stream().map(CartRecord::getGoodId).toList();
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 提取出购物车中的商品列表
List<Good> goodList = commonService.getItemsByIds(cartRecords, goodService, CartRecord::getGoodId);
// 封装goodMap(根据商品id查询商品)
Map<Long, Good> goodMap = new HashMap<>();
for (Good good : goodList) {
goodMap.put(good.getId(), good);
}
// 校验购物车商品
for (CartRecord cartRecord : cartRecords) {
Good good = goodMap.get(cartRecord.getGoodId());
Integer quantity = cartRecord.getQuantity();
goodService.checkGoodIsExist(good);
goodService.checkInventoryIsEnough(quantity, good.getInventory());
}
// 封装提交订单页的商品信息列表
List<CartOrderVO> cartOrderVOList = new ArrayList<>();
@ -259,8 +256,8 @@ public class CartRecordController {
Long goodId = buySingleGoodVerifyRequest.getGoodId();
Integer quantity = buySingleGoodVerifyRequest.getQuantity();
Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.SYSTEM_ERROR, "商品已下架或不存在");
ThrowUtils.throwIf(quantity > good.getInventory(), ErrorCode.SYSTEM_ERROR, "商品库存不足");
goodService.checkGoodIsExist(good);
goodService.checkInventoryIsEnough(quantity, good.getInventory());
return ResultUtils.success(true);
}

View File

@ -91,7 +91,7 @@ public class OrderController {
/**
* 小程序端用户创建常规类(服务类商品订单
* 小程序端用户创建常规类服务类商品订单
* @param generalGoodSingleBuyAddRequest 常规类商品单独购买创建请求体
* @return 是否创建成功
*/

View File

@ -65,6 +65,12 @@ public class PendingServiceGood implements Serializable {
private String timeSlot;
/**
* 是否可预约
*/
private Integer isAvailable;
/**
* 最小预约人数
*/

View File

@ -46,6 +46,12 @@ public class PendingServiceGoodVO implements Serializable {
private String timeSlot;
/**
* 是否可预约
*/
private Integer isAvailable;
/**
* 最小预约人数
*/

View File

@ -0,0 +1,22 @@
package com.cultural.heritage.service.common;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.function.Function;
public interface CommonService {
/**
* 取出一个集合的某个id列表, 去另外一个集合中筛选出属于这个id列表的集合
*/
<T, R> List<R> getItemsByIds(List<T> records, IService<R> genericService, Function<T, Long> getId);
/**
* 根据 ID 列表获取对应的实体列表
*/
<T> List<T> getListByIds(List<Long> ids, IService<T> genericService);
}

View File

@ -0,0 +1,47 @@
package com.cultural.heritage.service.common.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cultural.heritage.service.common.CommonService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class CommonServiceImpl implements CommonService {
/**
* 取出一个集合的某个id列表, 去另外一个集合中筛选出属于这个id列表的集合
*/
@Override
public <T, R> List<R> getItemsByIds(List<T> records, IService<R> genericService, Function<T, Long> getId) {
// 提取ID
List<Long> ids = records.stream()
.map(getId) // 提取每个元素的ID
.collect(Collectors.toList());
// 构造查询条件
QueryWrapper<R> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", ids);
// 返回查询结果
return genericService.list(queryWrapper);
}
/**
* 根据 ID 列表获取对应的实体列表
*/
@Override
public <T> List<T> getListByIds(List<Long> ids, IService<T> genericService) {
// 构造查询条件
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", ids); // 使用 IN 条件
// 调用具体的服务执行查询
return genericService.list(queryWrapper);
}
}

View File

@ -15,7 +15,7 @@ public interface CartExperienceService extends IService<CartExperience> {
/**
* 更新购物车的商品属性
*/
boolean updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request);
void updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request);
/**

View File

@ -14,7 +14,7 @@ public interface CartRecordService extends IService<CartRecord> {
/**
* 更新购物车的商品属性
*/
boolean updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request);
void updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request);
/**

View File

@ -3,12 +3,11 @@ package com.cultural.heritage.service.good;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cultural.heritage.model.dto.good.GoodQueryRequest;
import com.cultural.heritage.model.entity.CartExperience;
import com.cultural.heritage.model.entity.CartRecord;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public interface GoodService extends IService<Good> {
@ -18,12 +17,6 @@ public interface GoodService extends IService<Good> {
QueryWrapper<Good> getGoodQueryWrapper(GoodQueryRequest goodQueryRequest, boolean isServiceGood);
/**
* 根据商品类名查询商品列表
*/
List<Good> getGoodListByTypeName(String typeName);
/**
* 校验
*/
@ -43,4 +36,37 @@ public interface GoodService extends IService<Good> {
/**
* 判断商品是否存在或者下架
*/
void checkGoodIsExist(Good good);
/**
* 判断常规类商品库存是否充足
*/
void checkInventoryIsEnough(Integer neededQuantity, Integer actualQuantity);
/**
* 封装一个Map集合BookingOrderQueryRequest.toString()服务类商品待处理商品记录
*/
Map<String, PendingServiceGood> getPendingServiceGoodMap();
/**
* 校验购买的服务类商品预约情况是否合理
*/
void checkServiceGoodBookingDetailIsProperly(Long goodId, String reservationDate, String timeSlot, Integer quantity);
/**
* 校验购买的服务类购物车中的商品预约情况是否合理
*/
boolean checkServiceGoodCartBookingDetailIsProperly(Long goodId, String reservationDate, String timeSlot, Integer quantity, Map<String, PendingServiceGood> pendingServiceGoodMap, List<PendingServiceOrder> pendingServiceOrderList);
}

View File

@ -9,13 +9,13 @@ import com.cultural.heritage.exception.ThrowUtils;
import com.cultural.heritage.mapper.CartExperienceMapper;
import com.cultural.heritage.model.dto.cartService.CartExperienceAddRequest;
import com.cultural.heritage.model.dto.cartService.CartExperienceOrderItemAddRequest;
import com.cultural.heritage.model.entity.CartExperience;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceVO;
import com.cultural.heritage.service.common.CommonService;
import com.cultural.heritage.service.good.CartExperienceService;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.service.user.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
@ -46,48 +46,57 @@ public class CartExperienceServiceImpl extends ServiceImpl<CartExperienceMapper,
private UserService userService;
@Resource
private CommonService commonService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/**
* 更新购物车的商品属性
*/
@Override
public boolean updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request) {
public void updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
Long goodId = cartExperienceAddRequest.getGoodId();
Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品不存在或者已下架");
// 判断商品是否存在或者下架
goodService.checkGoodIsExist(good);
String reservationDate = cartExperienceAddRequest.getReservationDate();
String timeSlot = cartExperienceAddRequest.getTimeSlot();
Integer addQuantity = cartExperienceAddRequest.getQuantity();
QueryWrapper<CartExperience> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userId", userId);
queryWrapper.eq("goodId", goodId);
CartExperience cartExperience = this.baseMapper.selectOne(queryWrapper);
queryWrapper.eq("reservationDate", reservationDate);
queryWrapper.eq("timeSlot", timeSlot);
CartExperience cartExperience = this.getOne(queryWrapper);
if (cartExperience != null) {
// 判断数量是否超出库存
int currentQuantity = cartExperience.getQuantity() + cartExperienceAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 校验当前服务类商品的预约情况
Integer originQuantity = cartExperience.getQuantity();
goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, originQuantity + addQuantity);
// 如果购物车中已存在该商品, 就叠加数量
cartExperience.setQuantity(currentQuantity);
cartExperience.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(currentQuantity)));
cartExperience.setQuantity(originQuantity + addQuantity);
cartExperience.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(cartExperience.getQuantity())));
boolean result = this.updateById(cartExperience);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "更新购物车商品数量失败");
} else {
// 判断数量是否超出库存
Integer currentQuantity = cartExperienceAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 校验当前服务类商品的预约情况
goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, addQuantity);
// 如果购物车不存在该商品就向购物车中添加一项
CartExperience cartExperienceRecord = new CartExperience();
BeanUtils.copyProperties(cartExperienceAddRequest, cartExperienceRecord);
cartExperienceRecord.setUserId(userId);
cartExperienceRecord.setQuantity(addQuantity);
cartExperienceRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(cartExperienceRecord.getQuantity())));
// 校验
this.validCart(cartExperienceRecord, false);
boolean result = this.save(cartExperienceRecord);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
}
return true;
}
@ -174,23 +183,17 @@ public class CartExperienceServiceImpl extends ServiceImpl<CartExperienceMapper,
/**
* 校验购物车商品项的准确性
*/
private boolean validIsConsistent(CartExperience cartExperience, Good good) {
private boolean validIsConsistent(CartExperience cartExperience, Good good, Map<String, PendingServiceGood> pendingServiceGoodMap, List<PendingServiceOrder> pendingServiceOrderList) {
// 校验购物车中的商品是否存在
if (good == null || good.getIsShelves() == 0) {
log.info("商品不存在或者已下架, 购物车id为" + cartExperience.getId());
return false;
}
// 判断当前时间是否晚于预约时间
String reservationDate = cartExperience.getReservationDate();
String startTime = cartExperience.getTimeSlot().split("-")[0];
String advanceDateTimeStr = reservationDate + " " + startTime + ":00";
String currentDateTimeStr = DateUtil.now();
Date advanceDateTime = DateUtil.parse(advanceDateTimeStr, "yyyy-MM-dd HH:mm:ss");
Date currentDateTime = DateUtil.parse(currentDateTimeStr, "yyyy-MM-dd HH:mm:ss");
int result = DateUtil.compare(advanceDateTime, currentDateTime);
return result > 0;
String timeSlot = cartExperience.getTimeSlot();
Integer quantity = cartExperience.getQuantity();
// 校验购买的服务类购物车中的商品预约情况是否合理
return goodService.checkServiceGoodCartBookingDetailIsProperly(good.getId(), reservationDate, timeSlot, quantity, pendingServiceGoodMap, pendingServiceOrderList);
}
@ -230,19 +233,18 @@ public class CartExperienceServiceImpl extends ServiceImpl<CartExperienceMapper,
@Override
public List<Long> getInvalidCartIds(List<CartExperience> cartExperienceList) {
// 获取购物车的商品id列表
List<Long> goodIds = cartExperienceList.stream().map(CartExperience::getGoodId).toList();
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
List<Good> goodList = commonService.getItemsByIds(cartExperienceList, goodService, CartExperience::getGoodId);
// 封装map集合商品id, 商品详情信息
Map<Long, Good> map = new HashMap<>();
for (Good good : goodList) {
map.put(good.getId(), good);
}
Map<String, PendingServiceGood> pendingServiceGoodMap = goodService.getPendingServiceGoodMap();
List<PendingServiceOrder> pendingServiceOrderList = pendingServiceOrderService.list();
List<CartExperience> cartExperiences = cartExperienceList.stream().filter(cartExperience -> {
Long goodId = cartExperience.getGoodId();
Good good = map.get(goodId);
return !validIsConsistent(cartExperience, good);
return !validIsConsistent(cartExperience, good, pendingServiceGoodMap, pendingServiceOrderList);
}).toList();
return cartExperiences.stream().map(CartExperience::getId).toList();
}

View File

@ -13,6 +13,7 @@ import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.vo.cart.CartGoodVO;
import com.cultural.heritage.model.vo.cart.CartRecordVO;
import com.cultural.heritage.service.common.CommonService;
import com.cultural.heritage.service.good.CartRecordService;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.user.UserService;
@ -41,16 +42,20 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
@Resource
private UserService userService;
@Resource
private CommonService commonService;
/**
* 更新购物车的商品属性
*/
@Override
public boolean updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request) {
public void updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
Long goodId = cartRecordAddRequest.getGoodId();
Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品不存在或者已下架");
goodService.checkGoodIsExist(good);
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userId", userId);
queryWrapper.eq("goodId", goodId);
@ -58,9 +63,7 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
if (cartRecord != null) {
// 判断数量是否超出库存
int currentQuantity = cartRecord.getQuantity() + cartRecordAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
goodService.checkInventoryIsEnough(currentQuantity, good.getInventory());
// 如果购物车中已存在该商品, 就叠加数量
cartRecord.setQuantity(currentQuantity);
cartRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(currentQuantity)));
@ -69,9 +72,7 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
} else {
// 判断数量是否超出库存
Integer currentQuantity = cartRecordAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
goodService.checkInventoryIsEnough(currentQuantity, good.getInventory());
// 如果购物车不存在该商品就向购物车中添加一项
CartRecord cartGood = new CartRecord();
BeanUtils.copyProperties(cartRecordAddRequest, cartGood);
@ -82,7 +83,6 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
boolean result = this.save(cartGood);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
}
return true;
}
@ -156,17 +156,12 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
private boolean validIsConsistent(CartRecord cartRecord, Good good) {
// 校验购物车中的商品是否存在
if (good == null || good.getIsShelves() == 0) {
log.info("商品不存在或者已下架, 购物车id为" + cartRecord.getId());
return false;
}
// 校验购物车中的商品数量
Integer inventory = good.getInventory();
Integer quantity = cartRecord.getQuantity();
if (quantity > inventory) {
log.info("商品库存量不足, 购物车id为" + cartRecord.getId());
return false;
}
return true;
return quantity <= inventory;
}
@ -181,18 +176,12 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
// 封装map集合购物车id, 购买数量
Map<Long, Integer> map = new HashMap<>();
for (CartOrderItemAddRequest cartOrderItemAddRequest : cartOrderItemAddRequestList) {
Long cartRecordId = cartOrderItemAddRequest.getCartRecordId();
Integer quantity = cartOrderItemAddRequest.getQuantity();
map.put(cartRecordId, quantity);
map.put(cartOrderItemAddRequest.getCartRecordId(), cartOrderItemAddRequest.getQuantity());
}
// 修改购物车商品项的购买数量
List<Long> cartRecordIds = cartOrderItemAddRequestList.stream().map(CartOrderItemAddRequest::getCartRecordId).toList();
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartRecordIds);
List<CartRecord> cartRecordList = this.list(queryWrapper);
List<CartRecord> cartRecordList = commonService.getItemsByIds(cartOrderItemAddRequestList, this, CartOrderItemAddRequest::getCartRecordId);
for (CartRecord cartRecord : cartRecordList) {
Long id = cartRecord.getId();
Integer quantity = map.get(id);
Integer quantity = map.get(cartRecord.getId());
cartRecord.setQuantity(quantity);
}
List<Long> cartIds = getInvalidCartIds(cartRecordList);
@ -205,11 +194,8 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
*/
@Override
public List<Long> getInvalidCartIds(List<CartRecord> cartRecords) {
// 获取购物车的商品id列表
List<Long> goodIds = cartRecords.stream().map(CartRecord::getGoodId).toList();
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 获取购物车的商品列表
List<Good> goodList = commonService.getItemsByIds(cartRecords, goodService, CartRecord::getGoodId);
// 封装map集合商品id, 商品详情信息
Map<Long, Good> map = new HashMap<>();
for (Good good : goodList) {

View File

@ -1,29 +1,33 @@
package com.cultural.heritage.service.good.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cultural.heritage.common.ErrorCode;
import com.cultural.heritage.constant.CommonConstant;
import com.cultural.heritage.constant.OrderStatusConstant;
import com.cultural.heritage.exception.BusinessException;
import com.cultural.heritage.exception.ThrowUtils;
import com.cultural.heritage.mapper.CartExperienceMapper;
import com.cultural.heritage.mapper.CartRecordMapper;
import com.cultural.heritage.mapper.GoodMapper;
import com.cultural.heritage.model.dto.good.GoodQueryRequest;
import com.cultural.heritage.model.dto.order.BookingOrderQueryRequest;
import com.cultural.heritage.model.entity.CartExperience;
import com.cultural.heritage.model.entity.CartRecord;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.PendingServiceGoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.utils.SqlUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements GoodService {
@ -37,6 +41,14 @@ public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements Go
private CartExperienceMapper cartExperienceMapper;
@Resource
private PendingServiceGoodService pendingServiceGoodService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/**
* 商品查询条件
*/
@ -70,20 +82,7 @@ public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements Go
}
/**
* 根据商品类名查询商品列表
*/
@Override
public List<Good> getGoodListByTypeName(String typeName) {
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", typeName);
queryWrapper.eq("isShelves", 1);
List<Good> list = this.list(queryWrapper);
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>();
}
return list;
}
/**
@ -158,5 +157,118 @@ public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements Go
/**
* 判断商品是否存在或者下架
*/
@Override
public void checkGoodIsExist(Good good) {
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品不存在或者已下架");
}
/**
* 判断常规类商品库存是否充足
*/
@Override
public void checkInventoryIsEnough(Integer neededQuantity, Integer actualQuantity) {
ThrowUtils.throwIf(neededQuantity > actualQuantity, ErrorCode.OPERATION_ERROR, "商品库存不足");
}
/**
* 封装一个Map集合BookingOrderQueryRequest.toString()服务类商品待处理商品记录
*/
@Override
public Map<String, PendingServiceGood> getPendingServiceGoodMap() {
Map<String, PendingServiceGood> map = new HashMap<>();
List<PendingServiceGood> pendingServiceGoodList = pendingServiceGoodService.list();
for (PendingServiceGood pendingServiceGood : pendingServiceGoodList) {
Long goodId = pendingServiceGood.getGoodId();
String reservationDate = pendingServiceGood.getReservationDate();
String timeSlot = pendingServiceGood.getTimeSlot();
BookingOrderQueryRequest bookingOrderQueryRequest = new BookingOrderQueryRequest(goodId, reservationDate, timeSlot);
map.put(bookingOrderQueryRequest.toString(), pendingServiceGood);
}
return map;
}
/**
* 校验购买的服务类商品预约情况是否合理
*/
@Override
public void checkServiceGoodBookingDetailIsProperly(Long goodId, String reservationDate, String timeSlot, Integer quantity) {
BookingOrderQueryRequest bookingOrderQueryRequest = new BookingOrderQueryRequest(goodId, reservationDate, timeSlot);
Map<String, PendingServiceGood> pendingServiceGoodMap = this.getPendingServiceGoodMap();
PendingServiceGood pendingServiceGood = pendingServiceGoodMap.get(bookingOrderQueryRequest.toString());
Integer isAvailable = pendingServiceGood.getIsAvailable();
ThrowUtils.throwIf(isAvailable == 0, ErrorCode.OPERATION_ERROR, "当前时间段不可预约");
String startTime = timeSlot.split("-")[0];
String advanceDateTimeStr = reservationDate + " " + startTime + ":00";
String currentDateTimeStr = DateUtil.now();
Date advanceDateTime = DateUtil.parse(advanceDateTimeStr, "yyyy-MM-dd HH:mm:ss");
Date currentDateTime = DateUtil.parse(currentDateTimeStr, "yyyy-MM-dd HH:mm:ss");
int result = DateUtil.compare(advanceDateTime, currentDateTime);
ThrowUtils.throwIf(result <= 0, ErrorCode.OPERATION_ERROR, "当前时间段已过期");
Long pendingId = pendingServiceGood.getId();
QueryWrapper<PendingServiceOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pendingId", pendingId);
queryWrapper.eq("orderItemStatus", OrderStatusConstant.PENDING_SHIPMENT);
List<PendingServiceOrder> pendingServiceOrderList = pendingServiceOrderService.list(queryWrapper);
Integer totalNumber = 0;
for (PendingServiceOrder pendingServiceOrder : pendingServiceOrderList) {
totalNumber += pendingServiceOrder.getQuantity();
}
Integer maxNumber = pendingServiceGood.getMaxNumber();
ThrowUtils.throwIf(totalNumber + quantity > maxNumber, ErrorCode.OPERATION_ERROR, "当前预约数量已超过上限");
}
/**
* 校验购买的服务类购物车中的商品预约情况是否合理
*/
@Override
public boolean checkServiceGoodCartBookingDetailIsProperly(Long goodId, String reservationDate, String timeSlot, Integer quantity, Map<String, PendingServiceGood> pendingServiceGoodMap, List<PendingServiceOrder> pendingServiceOrderList) {
BookingOrderQueryRequest bookingOrderQueryRequest = new BookingOrderQueryRequest(goodId, reservationDate, timeSlot);
PendingServiceGood pendingServiceGood = pendingServiceGoodMap.get(bookingOrderQueryRequest.toString());
Integer isAvailable = pendingServiceGood.getIsAvailable();
if (isAvailable == 0) return false;
String startTime = timeSlot.split("-")[0];
String advanceDateTimeStr = reservationDate + " " + startTime + ":00";
String currentDateTimeStr = DateUtil.now();
Date advanceDateTime = DateUtil.parse(advanceDateTimeStr, "yyyy-MM-dd HH:mm:ss");
Date currentDateTime = DateUtil.parse(currentDateTimeStr, "yyyy-MM-dd HH:mm:ss");
int result = DateUtil.compare(advanceDateTime, currentDateTime);
if (result <= 0) return false;
Long pendingId = pendingServiceGood.getId();
pendingServiceOrderList = pendingServiceOrderList.stream().filter(pendingServiceOrder -> {
String orderItemStatus = pendingServiceOrder.getOrderItemStatus();
Long serviceOrderPendingId = pendingServiceOrder.getPendingId();
return orderItemStatus.equals(OrderStatusConstant.PENDING_SHIPMENT) && serviceOrderPendingId.equals(pendingId);
}).toList();
Integer totalNumber = 0;
for (PendingServiceOrder pendingServiceOrder : pendingServiceOrderList) {
totalNumber += pendingServiceOrder.getQuantity();
}
Integer maxNumber = pendingServiceGood.getMaxNumber();
return totalNumber + quantity <= maxNumber;
}
}

View File

@ -47,7 +47,6 @@ public interface OrderService extends IService<Order> {
void validSingleGoodOrder(GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest, boolean isGeneral);
/**
* 计算单个商品购买的总金额
*/

View File

@ -4,4 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.cultural.heritage.model.entity.PendingServiceOrder;
public interface PendingServiceOrderService extends IService<PendingServiceOrder> {
}

View File

@ -1,6 +1,5 @@
package com.cultural.heritage.service.order.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -31,6 +30,8 @@ import com.cultural.heritage.model.vo.coupon.CouponVO;
import com.cultural.heritage.service.good.*;
import com.cultural.heritage.service.order.OrderItemService;
import com.cultural.heritage.service.order.OrderService;
import com.cultural.heritage.service.order.PendingServiceGoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.utils.MultiDelayMessage;
import com.cultural.heritage.utils.OrderNumberUtils;
import com.cultural.heritage.utils.SqlUtils;
@ -92,6 +93,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
private UserCouponService userCouponService;
@Resource
private PendingServiceGoodService pendingServiceGoodService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/**
* 获取查询条件
*/
@ -314,22 +323,16 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
OrderItemMainInfoAddRequest orderItemMainInfoAddRequest = orderItemMainInfoAddRequestList.get(0);
Long goodId = orderItemMainInfoAddRequest.getGoodId();
Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品已下架或者不存在");
// 判断商品是否存在或者下架
goodService.checkGoodIsExist(good);
if (isGeneral) {
Integer quantity = orderItemMainInfoAddRequest.getQuantity();
ThrowUtils.throwIf(quantity > good.getInventory(), ErrorCode.OPERATION_ERROR, "商品库存不足");
goodService.checkInventoryIsEnough(orderItemMainInfoAddRequest.getQuantity(), good.getInventory());
} else {
String reservationDate = orderItemMainInfoAddRequest.getReservationDate();
String startTime = orderItemMainInfoAddRequest.getTimeSlot().split("-")[0];
String advanceDateTimeStr = reservationDate + " " + startTime + ":00";
String currentDateTimeStr = DateUtil.now();
Date advanceDateTime = DateUtil.parse(advanceDateTimeStr, "yyyy-MM-dd HH:mm:ss");
Date currentDateTime = DateUtil.parse(currentDateTimeStr, "yyyy-MM-dd HH:mm:ss");
int result = DateUtil.compare(advanceDateTime, currentDateTime);
ThrowUtils.throwIf(result <= 0, ErrorCode.OPERATION_ERROR, "当前时间段已过期");
String timeSlot = orderItemMainInfoAddRequest.getTimeSlot();
Integer quantity = orderItemMainInfoAddRequest.getQuantity();
goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, quantity);
}
}

View File

@ -8,4 +8,6 @@ import org.springframework.stereotype.Service;
@Service
public class PendingServiceOrderServiceImpl extends ServiceImpl<PendingServiceOrderMapper, PendingServiceOrder> implements PendingServiceOrderService {
}

View File

@ -3,6 +3,7 @@ package com.cultural.heritage.service.wx.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cultural.heritage.common.ErrorCode;
import com.cultural.heritage.config.WxOpenConfig;
import com.cultural.heritage.config.WxPayConfig;
@ -245,30 +246,58 @@ public class WeChatServiceImpl implements WeChatService {
// 获取订单明细所属的订单
Order order = orderService.getById(orderItems.getOrderId());
ThrowUtils.throwIf(order == null, ErrorCode.OPERATION_ERROR, "订单不存在");
// 判断该订单明细是否已经退款
QueryWrapper<PendingServiceOrder> pendingServiceOrderQueryWrapper = new QueryWrapper<>();
pendingServiceOrderQueryWrapper.eq("orderItemId", orderItemsId);
PendingServiceOrder pendingServiceOrder = pendingServiceOrderService.getOne(pendingServiceOrderQueryWrapper);
ThrowUtils.throwIf(pendingServiceOrder == null || !pendingServiceOrder.getOrderItemStatus().equals(OrderStatusConstant.PENDING_SHIPMENT), ErrorCode.OPERATION_ERROR, "服务类订单待处理记录不存在或者当前订单明细状态错误");
String orderNumber = order.getOrderNumber();
// 退款请求
CreateRequest createRequest = new CreateRequest();
// 商户订单号
createRequest.setOutTradeNo(orderNumber);
// 商户退款单号
String outRefundNo = RefundUtils.generateRefundNo();
String outRefundNo = RefundUtils.generateRefundPartNo(orderItemsId);
createRequest.setOutRefundNo(outRefundNo);
// 退款结果回调
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback");
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/part/callback");
// 退款金额
AmountReq amountReq = new AmountReq();
BigDecimal refundAmount;
CouponSnapshot couponSnapshot = order.getCouponSnapshot();
if (couponSnapshot == null) {
refundAmount = amount;
} else {
BigDecimal couponAmount = couponSnapshot.getConditionAmount();
BigDecimal totalAmount = order.getTotalAmount().add(couponAmount);
BigDecimal itemShare = amount.divide(totalAmount, 10, RoundingMode.HALF_UP);
BigDecimal itemCouponRefund = itemShare.multiply(couponAmount);
refundAmount = amount.subtract(itemCouponRefund);
// 判断是否为最后一个商品如果是则将剩余金额全部退款
QueryWrapper<OrderItems> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("orderId", order.getId());
long itemCount = orderItemService.count(queryWrapper);
QueryWrapper<RefundRecord> recordQueryWrapper = new QueryWrapper<>();
recordQueryWrapper.eq("outTradeNo", order.getOrderNumber());
long refundCount = refundRecordService.count(recordQueryWrapper);
if (itemCount - refundCount == 1) {
List<RefundRecord> refundRecords = refundRecordService.list(recordQueryWrapper);
BigDecimal refundTotalAmount = new BigDecimal("0.00");
for (RefundRecord refundRecord : refundRecords) {
BigDecimal recordRefundAmount = refundRecord.getRefundAmount();
refundTotalAmount = refundTotalAmount.add(recordRefundAmount);
}
refundAmount = order.getTotalAmount().subtract(refundTotalAmount);
} else {
BigDecimal couponAmount = couponSnapshot.getConditionAmount();
BigDecimal totalAmount = order.getTotalAmount().add(couponAmount);
BigDecimal itemShare = amount.divide(totalAmount, 10, RoundingMode.HALF_UP);
BigDecimal itemCouponRefund = itemShare.multiply(couponAmount);
refundAmount = amount.subtract(itemCouponRefund);
}
}
refundAmount = refundAmount.movePointRight(2).setScale(0, RoundingMode.HALF_UP);
amountReq.setRefund(refundAmount.longValue());
amountReq.setTotal(order.getTotalAmount().movePointRight(2).longValue());
@ -325,42 +354,59 @@ public class WeChatServiceImpl implements WeChatService {
boolean save = refundRecordService.save(refundRecord);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "退款记录生成失败");
// 恢复商品库存
QueryWrapper<OrderItems> orderItemsQueryWrapper = new QueryWrapper<>();
orderItemsQueryWrapper.eq("orderId", order.getId());
List<OrderItems> orderItemsList = orderItemService.list(orderItemsQueryWrapper);
// 获取商品id列表
List<Long> goodIds = orderItemsList.stream().map(orderItems -> {
GoodSnapshot goodSnapshot = orderItems.getGoodSnapshot();
return goodSnapshot.getId();
}).toList();
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
// 获取商品列表
List<Good> goodList = goodService.list(goodQueryWrapper);
// 封装为map集合商品id, 库存量,用来存储购买的商品id对应的购买数量
Map<Long, Integer> map = new HashMap<>();
for (OrderItems orderItems : orderItemsList) {
GoodSnapshot goodSnapshot = orderItems.getGoodSnapshot();
Long goodId = goodSnapshot.getId();
Integer quantity = orderItems.getQuantity();
map.put(goodId, quantity);
GoodTypeEnum orderTypeEnum = GoodTypeEnum.getEnumByValue(order.getOrderType());
if (GoodTypeEnum.SERVICE.equals(orderTypeEnum)) {
// 更新服务类订单待处理记录
QueryWrapper<PendingServiceOrder> orderQueryWrapper = new QueryWrapper<>();
orderQueryWrapper.eq("orderNumber", order.getOrderNumber());
List<PendingServiceOrder> pendingServiceOrderList = pendingServiceOrderService.list(orderQueryWrapper);
for (PendingServiceOrder pendingServiceOrder : pendingServiceOrderList) {
pendingServiceOrder.setOrderItemStatus(OrderStatusConstant.PAYMENT_REFUNDED);
}
boolean result = pendingServiceOrderService.updateBatchById(pendingServiceOrderList);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "服务类订单待处理记录批量更新失败");
} else {
// 恢复商品库存
QueryWrapper<OrderItems> orderItemsQueryWrapper = new QueryWrapper<>();
orderItemsQueryWrapper.eq("orderId", order.getId());
List<OrderItems> orderItemsList = orderItemService.list(orderItemsQueryWrapper);
// 获取商品id列表
List<Long> goodIds = orderItemsList.stream().map(orderItems -> {
GoodSnapshot goodSnapshot = orderItems.getGoodSnapshot();
return goodSnapshot.getId();
}).toList();
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
// 获取商品列表
List<Good> goodList = goodService.list(goodQueryWrapper);
// 封装为map集合商品id, 库存量,用来存储购买的商品id对应的购买数量
Map<Long, Integer> map = new HashMap<>();
for (OrderItems orderItems : orderItemsList) {
GoodSnapshot goodSnapshot = orderItems.getGoodSnapshot();
Long goodId = goodSnapshot.getId();
Integer quantity = orderItems.getQuantity();
map.put(goodId, quantity);
}
// 批量更新商品库存
for (Good good : goodList) {
Long goodId = good.getId();
// 已经下单购买的数量
Integer quantity = map.get(goodId);
// 原有的库存
Integer inventory = good.getInventory();
good.setInventory(quantity + inventory);
good.setUpdateTime(DateUtil.date());
}
boolean updateBatch = goodService.updateBatchById(goodList);
ThrowUtils.throwIf(!updateBatch, ErrorCode.SYSTEM_ERROR, "商品库存恢复失败");
System.out.println("---------------------------微信退款回调(结束)-------------------------------");
}
// 批量更新商品库存
for (Good good : goodList) {
Long goodId = good.getId();
// 已经下单购买的数量
Integer quantity = map.get(goodId);
// 原有的库存
Integer inventory = good.getInventory();
good.setInventory(quantity + inventory);
good.setUpdateTime(DateUtil.date());
}
boolean updateBatch = goodService.updateBatchById(goodList);
ThrowUtils.throwIf(!updateBatch, ErrorCode.SYSTEM_ERROR, "商品库存恢复失败");
System.out.println("---------------------------微信退款回调(结束)-------------------------------");
return true;
}
@ -372,9 +418,49 @@ public class WeChatServiceImpl implements WeChatService {
*/
@Override
public boolean refundPartCallback(RefundNotification refundNotification) {
return false;
}
System.out.println("---------------------------微信退款回调(开始)-------------------------------");
// 获取订单信息
String orderIdByString = refundNotification.getOutTradeNo();
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("orderNumber", orderIdByString);
Order order = orderService.getOne(queryWrapper);
if (order == null) {
log.error("订单不存在");
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + orderIdByString);
}
// 生成退款记录
RefundRecord refundRecord = new RefundRecord();
refundRecord.setOutTradeNo(refundNotification.getOutTradeNo());
refundRecord.setOutRefundNo(refundNotification.getOutRefundNo());
refundRecord.setRefundAmount(order.getTotalAmount());
boolean save = refundRecordService.save(refundRecord);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "退款记录生成失败");
String outRefundNo = refundNotification.getOutRefundNo();
String orderItemId = RefundUtils.parseRefundNoToItemId(outRefundNo);
GoodTypeEnum orderTypeEnum = GoodTypeEnum.getEnumByValue(order.getOrderType());
if (GoodTypeEnum.SERVICE.equals(orderTypeEnum)) {
// 更新服务类订单待处理记录
UpdateWrapper<PendingServiceOrder> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("orderItemId", orderItemId).set("orderItemStatus", OrderStatusConstant.PAYMENT_REFUNDED);
boolean update = pendingServiceOrderService.update(updateWrapper);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "服务类订单待处理记录状态更新失败");
} else {
// 恢复商品库存
OrderItems orderItems = orderItemService.getById(orderItemId);
Long id = orderItems.getGoodSnapshot().getId();
Good good = goodService.getById(id);
ThrowUtils.throwIf(good == null, ErrorCode.OPERATION_ERROR, "当前商品不存在");
good.setInventory(good.getInventory() + orderItems.getQuantity());
boolean update = goodService.updateById(good);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "商品库存恢复失败");
}
return true;
}
//

View File

@ -6,7 +6,7 @@ import java.util.Random;
public class RefundUtils {
// 生成唯一的退款单号格式为 yyyyMMddHHmmssSSS + 随机数
// 生成唯一的全额退款单号格式为 yyyyMMddHHmmssSSS + 随机数
public static String generateRefundNo() {
// 获取当前时间的时间戳
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
@ -18,4 +18,36 @@ public class RefundUtils {
return timestamp + randomNum;
}
// 生成唯一的部分退款单号格式为 yyyyMMddHHmmssSSS + 订单明细
public static String generateRefundPartNo(String orderItemId) {
// 获取当前时间的时间戳
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
String orderItemString = padString(orderItemId);
// 拼接退款单号
return timestamp + orderItemString;
}
// 将退款单号解析为订单明细id
public static String parseRefundNoToItemId(String outRefundNo) {
// 提取剩下的原始数字部分
String original = outRefundNo.substring(17); // 获取从第18位开始的部分
// 去掉前导0
original = original.replaceAll("^0+", ""); // 正则表达式去除开头的0
return original; // 返回提取的原始字符串
}
public static String padString(String input) {
if (input.length() < 4) {
input = String.format("%04d", Integer.parseInt(input)); // 补齐前导0
}
return input;
}
}