更新了服务类订单模块

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 = "已退款"; String PAYMENT_REFUNDED = "已退款";
} }

View File

@ -1,7 +1,6 @@
package com.cultural.heritage.controller.good; package com.cultural.heritage.controller.good;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cultural.heritage.common.BaseResponse; import com.cultural.heritage.common.BaseResponse;
import com.cultural.heritage.common.ErrorCode; 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.CartExperienceAddRequest;
import com.cultural.heritage.model.dto.cartService.CartExperienceUpdateRequest; import com.cultural.heritage.model.dto.cartService.CartExperienceUpdateRequest;
import com.cultural.heritage.model.dto.order.BuySingleServiceGoodVerifyRequest; import com.cultural.heritage.model.dto.order.BuySingleServiceGoodVerifyRequest;
import com.cultural.heritage.model.entity.CartExperience; import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO; import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceOrderVO; import com.cultural.heritage.model.vo.cartService.CartExperienceOrderVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceVO; 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.CartExperienceService;
import com.cultural.heritage.service.good.GoodService; import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.service.user.UserService; import com.cultural.heritage.service.user.UserService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@ -55,6 +54,15 @@ public class CartExperienceController {
private UserService userService; private UserService userService;
@Resource
private CommonService commonService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/** /**
* 小程序端用户添加服务类商品至购物车 * 小程序端用户添加服务类商品至购物车
@ -86,11 +94,8 @@ public class CartExperienceController {
} }
userService.getLoginUser(request); userService.getLoginUser(request);
// 获取购物车id列表 // 获取服务类购物车商品列表
List<Long> cartIds = cartExperienceUpdateRequestList.stream().map(CartExperienceUpdateRequest::getId).toList(); List<CartExperience> cartExperienceList = commonService.getItemsByIds(cartExperienceUpdateRequestList, cartExperienceService, CartExperienceUpdateRequest::getId);
QueryWrapper<CartExperience> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartIds);
List<CartExperience> cartExperienceList = cartExperienceService.list(queryWrapper);
// 封装map集合购物车id, 商品数量 // 封装map集合购物车id, 商品数量
Map<Long, Integer> QuantityMap = new HashMap<>(); Map<Long, Integer> QuantityMap = new HashMap<>();
@ -108,11 +113,8 @@ public class CartExperienceController {
timeSlotMap.put(id, timeSlot); timeSlotMap.put(id, timeSlot);
} }
// 获取商品id列表 // 获取商品列表
List<Long> goodIds = cartExperienceList.stream().map(CartExperience::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartExperienceList, goodService, CartExperience::getGoodId);
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(goodQueryWrapper);
// 封装map集合商品id, 商品价格 // 封装map集合商品id, 商品价格
Map<Long, BigDecimal> priceMap = new HashMap<>(); Map<Long, BigDecimal> priceMap = new HashMap<>();
@ -219,18 +221,11 @@ public class CartExperienceController {
} }
userService.getLoginUser(request); userService.getLoginUser(request);
List<Long> cartExperienceIds = commonBatchRequest.getIdList(); List<Long> cartExperienceIds = commonBatchRequest.getIdList();
List<CartExperience> cartExperienceList = cartExperienceService.list(); // 获取购物车信息列表
// 获取购物车列表信息 List<CartExperience> cartExperiences = commonService.getListByIds(cartExperienceIds, cartExperienceService);
List<CartExperience> cartExperiences = cartExperienceList.stream().filter(cartExperience -> {
Long id = cartExperience.getId();
return cartExperienceIds.contains(id);
}).toList();
// 提取出购物车中的商品id列表 // 获取购物车中的商品列表
List<Long> goodIds = cartExperiences.stream().map(CartExperience::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartExperiences, goodService, CartExperience::getGoodId);
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 封装goodMap(根据商品id查询商品) // 封装goodMap(根据商品id查询商品)
Map<Long, Good> goodMap = new HashMap<>(); Map<Long, Good> goodMap = new HashMap<>();
@ -238,6 +233,22 @@ public class CartExperienceController {
goodMap.put(good.getId(), good); 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<>(); List<CartExperienceOrderVO> cartOrderVOList = new ArrayList<>();
for (CartExperience cartExperience : cartExperiences) { for (CartExperience cartExperience : cartExperiences) {
@ -276,22 +287,16 @@ public class CartExperienceController {
} }
userService.getLoginUser(request); userService.getLoginUser(request);
Long goodId = buySingleServiceGoodVerifyRequest.getGoodId(); Long goodId = buySingleServiceGoodVerifyRequest.getGoodId();
// 校验商品是否存在或者下架
Good good = goodService.getById(goodId); Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.SYSTEM_ERROR, "商品已下架或不存在"); goodService.checkGoodIsExist(good);
String reservationDate = buySingleServiceGoodVerifyRequest.getReservationDate(); String reservationDate = buySingleServiceGoodVerifyRequest.getReservationDate();
String timeSlot = buySingleServiceGoodVerifyRequest.getTimeSlot(); String timeSlot = buySingleServiceGoodVerifyRequest.getTimeSlot();
Integer quantity = buySingleServiceGoodVerifyRequest.getQuantity();
String startTime = timeSlot.split("-")[0]; // 校验购买的服务类商品预约情况是否合理
String advanceDateTimeStr = reservationDate + " " + startTime + ":00"; goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, quantity);
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, "当前时间段已过期");
return ResultUtils.success(true); 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.CartGoodVO;
import com.cultural.heritage.model.vo.cart.CartOrderVO; import com.cultural.heritage.model.vo.cart.CartOrderVO;
import com.cultural.heritage.model.vo.cart.CartRecordVO; 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.CartRecordService;
import com.cultural.heritage.service.good.GoodService; import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.user.UserService; import com.cultural.heritage.service.user.UserService;
@ -41,6 +42,10 @@ import java.util.*;
public class CartRecordController { public class CartRecordController {
@Resource
private CommonService commonService;
@Resource @Resource
private CartRecordService cartRecordService; private CartRecordService cartRecordService;
@ -82,25 +87,17 @@ public class CartRecordController {
} }
userService.getLoginUser(request); userService.getLoginUser(request);
// 获取购物车id列表 // 获取购物车列表
List<Long> cartIds = cartRecordUpdateRequestList.stream().map(CartRecordUpdateRequest::getId).toList(); List<CartRecord> cartRecordList = commonService.getItemsByIds(cartRecordUpdateRequestList, cartRecordService, CartRecordUpdateRequest::getId);
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartIds);
List<CartRecord> cartRecordList = cartRecordService.list(queryWrapper);
// 封装map集合购物车id, 商品数量 // 封装map集合购物车id, 商品数量
Map<Long, Integer> QuantityMap = new HashMap<>(); Map<Long, Integer> QuantityMap = new HashMap<>();
for (CartRecordUpdateRequest cartRecordUpdateRequest : cartRecordUpdateRequestList) { for (CartRecordUpdateRequest cartRecordUpdateRequest : cartRecordUpdateRequestList) {
Long id = cartRecordUpdateRequest.getId(); QuantityMap.put(cartRecordUpdateRequest.getId(), cartRecordUpdateRequest.getQuantity());
Integer quantity = cartRecordUpdateRequest.getQuantity();
QuantityMap.put(id, quantity);
} }
// 获取商品id列表 // 获取商品列表
List<Long> goodIds = cartRecordList.stream().map(CartRecord::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartRecordList, goodService, CartRecord::getGoodId);
QueryWrapper<Good> goodQueryWrapper = new QueryWrapper<>();
goodQueryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(goodQueryWrapper);
// 封装map集合商品id, 商品价格 // 封装map集合商品id, 商品价格
Map<Long, BigDecimal> priceMap = new HashMap<>(); Map<Long, BigDecimal> priceMap = new HashMap<>();
@ -134,7 +131,7 @@ public class CartRecordController {
@PostMapping("/delete") @PostMapping("/delete")
@Operation(summary = "小程序端用户删除常规类购物车中的物品", description = "参数:购物车记录删除请求体(商品id列表如[2,3,4])权限所有人方法名deleteCart") @Operation(summary = "小程序端用户删除常规类购物车中的物品", description = "参数:购物车记录删除请求体(商品id列表如[2,3,4])权限所有人方法名deleteCart")
public BaseResponse<Boolean> deleteCart(@RequestBody CommonBatchRequest commonBatchRequest, HttpServletRequest request) { 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); throw new BusinessException(ErrorCode.PARAMS_ERROR);
} }
userService.getLoginUser(request); userService.getLoginUser(request);
@ -197,29 +194,29 @@ public class CartRecordController {
@PostMapping("/submit/list") @PostMapping("/submit/list")
@Operation(summary = "小程序端显示常规类购物车提交订单页的商品信息", description = "参数:购物车id列表权限所有人方法名listCartRecord") @Operation(summary = "小程序端显示常规类购物车提交订单页的商品信息", description = "参数:购物车id列表权限所有人方法名listCartRecord")
public BaseResponse<List<CartOrderVO>> listCartRecord(@RequestBody CommonBatchRequest commonBatchRequest, HttpServletRequest request) { 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); throw new BusinessException(ErrorCode.PARAMS_ERROR);
} }
userService.getLoginUser(request); userService.getLoginUser(request);
List<Long> cartRecordIds = commonBatchRequest.getIdList(); List<Long> cartRecordIds = commonBatchRequest.getIdList();
List<CartRecord> cartRecordList = cartRecordService.list(); // 根据id列表获取购物车信息列表
// 获取购物车列表信息 List<CartRecord> cartRecords = commonService.getListByIds(cartRecordIds, cartRecordService);
List<CartRecord> cartRecords = cartRecordList.stream().filter(cartRecord -> {
Long id = cartRecord.getId();
return cartRecordIds.contains(id);
}).toList();
// 提取出购物车中的商品id列表 // 提取出购物车中的商品列表
List<Long> goodIds = cartRecords.stream().map(CartRecord::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartRecords, goodService, CartRecord::getGoodId);
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 封装goodMap(根据商品id查询商品) // 封装goodMap(根据商品id查询商品)
Map<Long, Good> goodMap = new HashMap<>(); Map<Long, Good> goodMap = new HashMap<>();
for (Good good : goodList) { for (Good good : goodList) {
goodMap.put(good.getId(), good); 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<>(); List<CartOrderVO> cartOrderVOList = new ArrayList<>();
@ -259,8 +256,8 @@ public class CartRecordController {
Long goodId = buySingleGoodVerifyRequest.getGoodId(); Long goodId = buySingleGoodVerifyRequest.getGoodId();
Integer quantity = buySingleGoodVerifyRequest.getQuantity(); Integer quantity = buySingleGoodVerifyRequest.getQuantity();
Good good = goodService.getById(goodId); Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.SYSTEM_ERROR, "商品已下架或不存在"); goodService.checkGoodIsExist(good);
ThrowUtils.throwIf(quantity > good.getInventory(), ErrorCode.SYSTEM_ERROR, "商品库存不足"); goodService.checkInventoryIsEnough(quantity, good.getInventory());
return ResultUtils.success(true); return ResultUtils.success(true);
} }

View File

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

View File

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

View File

@ -46,6 +46,12 @@ public class PendingServiceGoodVO implements Serializable {
private String timeSlot; 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.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.cultural.heritage.model.dto.good.GoodQueryRequest; import com.cultural.heritage.model.dto.good.GoodQueryRequest;
import com.cultural.heritage.model.entity.CartExperience; import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.entity.CartRecord;
import com.cultural.heritage.model.entity.Good;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map;
public interface GoodService extends IService<Good> { public interface GoodService extends IService<Good> {
@ -18,12 +17,6 @@ public interface GoodService extends IService<Good> {
QueryWrapper<Good> getGoodQueryWrapper(GoodQueryRequest goodQueryRequest, boolean isServiceGood); 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.mapper.CartExperienceMapper;
import com.cultural.heritage.model.dto.cartService.CartExperienceAddRequest; import com.cultural.heritage.model.dto.cartService.CartExperienceAddRequest;
import com.cultural.heritage.model.dto.cartService.CartExperienceOrderItemAddRequest; import com.cultural.heritage.model.dto.cartService.CartExperienceOrderItemAddRequest;
import com.cultural.heritage.model.entity.CartExperience; import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO; import com.cultural.heritage.model.vo.cartService.CartExperienceGoodVO;
import com.cultural.heritage.model.vo.cartService.CartExperienceVO; 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.CartExperienceService;
import com.cultural.heritage.service.good.GoodService; import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.order.PendingServiceOrderService;
import com.cultural.heritage.service.user.UserService; import com.cultural.heritage.service.user.UserService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -46,48 +46,57 @@ public class CartExperienceServiceImpl extends ServiceImpl<CartExperienceMapper,
private UserService userService; private UserService userService;
@Resource
private CommonService commonService;
@Resource
private PendingServiceOrderService pendingServiceOrderService;
/** /**
* 更新购物车的商品属性 * 更新购物车的商品属性
*/ */
@Override @Override
public boolean updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request) { public void updateCartGoodAttribute(CartExperienceAddRequest cartExperienceAddRequest, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request); User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId(); Long userId = loginUser.getId();
Long goodId = cartExperienceAddRequest.getGoodId(); Long goodId = cartExperienceAddRequest.getGoodId();
Good good = goodService.getById(goodId); 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<CartExperience> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userId", userId); queryWrapper.eq("userId", userId);
queryWrapper.eq("goodId", goodId); 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) { if (cartExperience != null) {
// 判断数量是否超出库存 // 校验当前服务类商品的预约情况
int currentQuantity = cartExperience.getQuantity() + cartExperienceAddRequest.getQuantity(); Integer originQuantity = cartExperience.getQuantity();
if (currentQuantity > good.getInventory()) { goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, originQuantity + addQuantity);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 如果购物车中已存在该商品, 就叠加数量 // 如果购物车中已存在该商品, 就叠加数量
cartExperience.setQuantity(currentQuantity); cartExperience.setQuantity(originQuantity + addQuantity);
cartExperience.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(currentQuantity))); cartExperience.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(cartExperience.getQuantity())));
boolean result = this.updateById(cartExperience); boolean result = this.updateById(cartExperience);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "更新购物车商品数量失败"); ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "更新购物车商品数量失败");
} else { } else {
// 判断数量是否超出库存 // 校验当前服务类商品的预约情况
Integer currentQuantity = cartExperienceAddRequest.getQuantity(); goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, addQuantity);
if (currentQuantity > good.getInventory()) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 如果购物车不存在该商品就向购物车中添加一项 // 如果购物车不存在该商品就向购物车中添加一项
CartExperience cartExperienceRecord = new CartExperience(); CartExperience cartExperienceRecord = new CartExperience();
BeanUtils.copyProperties(cartExperienceAddRequest, cartExperienceRecord); BeanUtils.copyProperties(cartExperienceAddRequest, cartExperienceRecord);
cartExperienceRecord.setUserId(userId); cartExperienceRecord.setUserId(userId);
cartExperienceRecord.setQuantity(addQuantity);
cartExperienceRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(cartExperienceRecord.getQuantity()))); cartExperienceRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(cartExperienceRecord.getQuantity())));
// 校验 // 校验
this.validCart(cartExperienceRecord, false); this.validCart(cartExperienceRecord, false);
boolean result = this.save(cartExperienceRecord); boolean result = this.save(cartExperienceRecord);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); 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) { if (good == null || good.getIsShelves() == 0) {
log.info("商品不存在或者已下架, 购物车id为" + cartExperience.getId());
return false; return false;
} }
// 判断当前时间是否晚于预约时间 // 判断当前时间是否晚于预约时间
String reservationDate = cartExperience.getReservationDate(); String reservationDate = cartExperience.getReservationDate();
String startTime = cartExperience.getTimeSlot().split("-")[0]; String timeSlot = cartExperience.getTimeSlot();
String advanceDateTimeStr = reservationDate + " " + startTime + ":00"; Integer quantity = cartExperience.getQuantity();
String currentDateTimeStr = DateUtil.now(); // 校验购买的服务类购物车中的商品预约情况是否合理
return goodService.checkServiceGoodCartBookingDetailIsProperly(good.getId(), reservationDate, timeSlot, quantity, pendingServiceGoodMap, pendingServiceOrderList);
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;
} }
@ -230,19 +233,18 @@ public class CartExperienceServiceImpl extends ServiceImpl<CartExperienceMapper,
@Override @Override
public List<Long> getInvalidCartIds(List<CartExperience> cartExperienceList) { public List<Long> getInvalidCartIds(List<CartExperience> cartExperienceList) {
// 获取购物车的商品id列表 // 获取购物车的商品id列表
List<Long> goodIds = cartExperienceList.stream().map(CartExperience::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartExperienceList, goodService, CartExperience::getGoodId);
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 封装map集合商品id, 商品详情信息 // 封装map集合商品id, 商品详情信息
Map<Long, Good> map = new HashMap<>(); Map<Long, Good> map = new HashMap<>();
for (Good good : goodList) { for (Good good : goodList) {
map.put(good.getId(), good); map.put(good.getId(), good);
} }
Map<String, PendingServiceGood> pendingServiceGoodMap = goodService.getPendingServiceGoodMap();
List<PendingServiceOrder> pendingServiceOrderList = pendingServiceOrderService.list();
List<CartExperience> cartExperiences = cartExperienceList.stream().filter(cartExperience -> { List<CartExperience> cartExperiences = cartExperienceList.stream().filter(cartExperience -> {
Long goodId = cartExperience.getGoodId(); Long goodId = cartExperience.getGoodId();
Good good = map.get(goodId); Good good = map.get(goodId);
return !validIsConsistent(cartExperience, good); return !validIsConsistent(cartExperience, good, pendingServiceGoodMap, pendingServiceOrderList);
}).toList(); }).toList();
return cartExperiences.stream().map(CartExperience::getId).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.entity.User;
import com.cultural.heritage.model.vo.cart.CartGoodVO; import com.cultural.heritage.model.vo.cart.CartGoodVO;
import com.cultural.heritage.model.vo.cart.CartRecordVO; 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.CartRecordService;
import com.cultural.heritage.service.good.GoodService; import com.cultural.heritage.service.good.GoodService;
import com.cultural.heritage.service.user.UserService; import com.cultural.heritage.service.user.UserService;
@ -41,16 +42,20 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
@Resource @Resource
private UserService userService; private UserService userService;
@Resource
private CommonService commonService;
/** /**
* 更新购物车的商品属性 * 更新购物车的商品属性
*/ */
@Override @Override
public boolean updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request) { public void updateCartGoodAttribute(CartRecordAddRequest cartRecordAddRequest, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request); User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId(); Long userId = loginUser.getId();
Long goodId = cartRecordAddRequest.getGoodId(); Long goodId = cartRecordAddRequest.getGoodId();
Good good = goodService.getById(goodId); Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品不存在或者已下架"); goodService.checkGoodIsExist(good);
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>(); QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userId", userId); queryWrapper.eq("userId", userId);
queryWrapper.eq("goodId", goodId); queryWrapper.eq("goodId", goodId);
@ -58,9 +63,7 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
if (cartRecord != null) { if (cartRecord != null) {
// 判断数量是否超出库存 // 判断数量是否超出库存
int currentQuantity = cartRecord.getQuantity() + cartRecordAddRequest.getQuantity(); int currentQuantity = cartRecord.getQuantity() + cartRecordAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) { goodService.checkInventoryIsEnough(currentQuantity, good.getInventory());
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 如果购物车中已存在该商品, 就叠加数量 // 如果购物车中已存在该商品, 就叠加数量
cartRecord.setQuantity(currentQuantity); cartRecord.setQuantity(currentQuantity);
cartRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(currentQuantity))); cartRecord.setSubtotal(good.getPrice().multiply(BigDecimal.valueOf(currentQuantity)));
@ -69,9 +72,7 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
} else { } else {
// 判断数量是否超出库存 // 判断数量是否超出库存
Integer currentQuantity = cartRecordAddRequest.getQuantity(); Integer currentQuantity = cartRecordAddRequest.getQuantity();
if (currentQuantity > good.getInventory()) { goodService.checkInventoryIsEnough(currentQuantity, good.getInventory());
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "商品库存不足, 无法添加");
}
// 如果购物车不存在该商品就向购物车中添加一项 // 如果购物车不存在该商品就向购物车中添加一项
CartRecord cartGood = new CartRecord(); CartRecord cartGood = new CartRecord();
BeanUtils.copyProperties(cartRecordAddRequest, cartGood); BeanUtils.copyProperties(cartRecordAddRequest, cartGood);
@ -82,7 +83,6 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
boolean result = this.save(cartGood); boolean result = this.save(cartGood);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); 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) { private boolean validIsConsistent(CartRecord cartRecord, Good good) {
// 校验购物车中的商品是否存在 // 校验购物车中的商品是否存在
if (good == null || good.getIsShelves() == 0) { if (good == null || good.getIsShelves() == 0) {
log.info("商品不存在或者已下架, 购物车id为" + cartRecord.getId());
return false; return false;
} }
// 校验购物车中的商品数量 // 校验购物车中的商品数量
Integer inventory = good.getInventory(); Integer inventory = good.getInventory();
Integer quantity = cartRecord.getQuantity(); Integer quantity = cartRecord.getQuantity();
if (quantity > inventory) { return quantity <= inventory;
log.info("商品库存量不足, 购物车id为" + cartRecord.getId());
return false;
}
return true;
} }
@ -181,18 +176,12 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
// 封装map集合购物车id, 购买数量 // 封装map集合购物车id, 购买数量
Map<Long, Integer> map = new HashMap<>(); Map<Long, Integer> map = new HashMap<>();
for (CartOrderItemAddRequest cartOrderItemAddRequest : cartOrderItemAddRequestList) { for (CartOrderItemAddRequest cartOrderItemAddRequest : cartOrderItemAddRequestList) {
Long cartRecordId = cartOrderItemAddRequest.getCartRecordId(); map.put(cartOrderItemAddRequest.getCartRecordId(), cartOrderItemAddRequest.getQuantity());
Integer quantity = cartOrderItemAddRequest.getQuantity();
map.put(cartRecordId, quantity);
} }
// 修改购物车商品项的购买数量 // 修改购物车商品项的购买数量
List<Long> cartRecordIds = cartOrderItemAddRequestList.stream().map(CartOrderItemAddRequest::getCartRecordId).toList(); List<CartRecord> cartRecordList = commonService.getItemsByIds(cartOrderItemAddRequestList, this, CartOrderItemAddRequest::getCartRecordId);
QueryWrapper<CartRecord> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", cartRecordIds);
List<CartRecord> cartRecordList = this.list(queryWrapper);
for (CartRecord cartRecord : cartRecordList) { for (CartRecord cartRecord : cartRecordList) {
Long id = cartRecord.getId(); Integer quantity = map.get(cartRecord.getId());
Integer quantity = map.get(id);
cartRecord.setQuantity(quantity); cartRecord.setQuantity(quantity);
} }
List<Long> cartIds = getInvalidCartIds(cartRecordList); List<Long> cartIds = getInvalidCartIds(cartRecordList);
@ -205,11 +194,8 @@ public class CartRecordServiceImpl extends ServiceImpl<CartRecordMapper, CartRec
*/ */
@Override @Override
public List<Long> getInvalidCartIds(List<CartRecord> cartRecords) { public List<Long> getInvalidCartIds(List<CartRecord> cartRecords) {
// 获取购物车的商品id列表 // 获取购物车的商品列表
List<Long> goodIds = cartRecords.stream().map(CartRecord::getGoodId).toList(); List<Good> goodList = commonService.getItemsByIds(cartRecords, goodService, CartRecord::getGoodId);
QueryWrapper<Good> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", goodIds);
List<Good> goodList = goodService.list(queryWrapper);
// 封装map集合商品id, 商品详情信息 // 封装map集合商品id, 商品详情信息
Map<Long, Good> map = new HashMap<>(); Map<Long, Good> map = new HashMap<>();
for (Good good : goodList) { for (Good good : goodList) {

View File

@ -1,29 +1,33 @@
package com.cultural.heritage.service.good.impl; 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.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.common.ErrorCode;
import com.cultural.heritage.constant.CommonConstant; import com.cultural.heritage.constant.CommonConstant;
import com.cultural.heritage.constant.OrderStatusConstant;
import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.exception.BusinessException;
import com.cultural.heritage.exception.ThrowUtils;
import com.cultural.heritage.mapper.CartExperienceMapper; import com.cultural.heritage.mapper.CartExperienceMapper;
import com.cultural.heritage.mapper.CartRecordMapper; import com.cultural.heritage.mapper.CartRecordMapper;
import com.cultural.heritage.mapper.GoodMapper; import com.cultural.heritage.mapper.GoodMapper;
import com.cultural.heritage.model.dto.good.GoodQueryRequest; import com.cultural.heritage.model.dto.good.GoodQueryRequest;
import com.cultural.heritage.model.dto.order.BookingOrderQueryRequest; import com.cultural.heritage.model.dto.order.BookingOrderQueryRequest;
import com.cultural.heritage.model.entity.CartExperience; import com.cultural.heritage.model.entity.*;
import com.cultural.heritage.model.entity.CartRecord;
import com.cultural.heritage.model.entity.Good;
import com.cultural.heritage.service.good.GoodService; 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 com.cultural.heritage.utils.SqlUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Service @Service
public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements GoodService { 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; 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); 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; import com.cultural.heritage.model.entity.PendingServiceOrder;
public interface PendingServiceOrderService extends IService<PendingServiceOrder> { public interface PendingServiceOrderService extends IService<PendingServiceOrder> {
} }

View File

@ -1,6 +1,5 @@
package com.cultural.heritage.service.order.impl; 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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 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.good.*;
import com.cultural.heritage.service.order.OrderItemService; import com.cultural.heritage.service.order.OrderItemService;
import com.cultural.heritage.service.order.OrderService; 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.MultiDelayMessage;
import com.cultural.heritage.utils.OrderNumberUtils; import com.cultural.heritage.utils.OrderNumberUtils;
import com.cultural.heritage.utils.SqlUtils; import com.cultural.heritage.utils.SqlUtils;
@ -92,6 +93,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
private UserCouponService userCouponService; 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); OrderItemMainInfoAddRequest orderItemMainInfoAddRequest = orderItemMainInfoAddRequestList.get(0);
Long goodId = orderItemMainInfoAddRequest.getGoodId(); Long goodId = orderItemMainInfoAddRequest.getGoodId();
Good good = goodService.getById(goodId); Good good = goodService.getById(goodId);
ThrowUtils.throwIf(good == null || good.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "商品已下架或者不存在"); // 判断商品是否存在或者下架
goodService.checkGoodIsExist(good);
if (isGeneral) { if (isGeneral) {
Integer quantity = orderItemMainInfoAddRequest.getQuantity(); goodService.checkInventoryIsEnough(orderItemMainInfoAddRequest.getQuantity(), good.getInventory());
ThrowUtils.throwIf(quantity > good.getInventory(), ErrorCode.OPERATION_ERROR, "商品库存不足");
} else { } else {
String reservationDate = orderItemMainInfoAddRequest.getReservationDate(); String reservationDate = orderItemMainInfoAddRequest.getReservationDate();
String startTime = orderItemMainInfoAddRequest.getTimeSlot().split("-")[0]; String timeSlot = orderItemMainInfoAddRequest.getTimeSlot();
String advanceDateTimeStr = reservationDate + " " + startTime + ":00"; Integer quantity = orderItemMainInfoAddRequest.getQuantity();
String currentDateTimeStr = DateUtil.now(); goodService.checkServiceGoodBookingDetailIsProperly(goodId, reservationDate, timeSlot, quantity);
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, "当前时间段已过期");
} }
} }

View File

@ -8,4 +8,6 @@ import org.springframework.stereotype.Service;
@Service @Service
public class PendingServiceOrderServiceImpl extends ServiceImpl<PendingServiceOrderMapper, PendingServiceOrder> implements PendingServiceOrderService { 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 cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.common.ErrorCode;
import com.cultural.heritage.config.WxOpenConfig; import com.cultural.heritage.config.WxOpenConfig;
import com.cultural.heritage.config.WxPayConfig; import com.cultural.heritage.config.WxPayConfig;
@ -245,23 +246,49 @@ public class WeChatServiceImpl implements WeChatService {
// 获取订单明细所属的订单 // 获取订单明细所属的订单
Order order = orderService.getById(orderItems.getOrderId()); Order order = orderService.getById(orderItems.getOrderId());
ThrowUtils.throwIf(order == null, ErrorCode.OPERATION_ERROR, "订单不存在"); 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(); String orderNumber = order.getOrderNumber();
// 退款请求 // 退款请求
CreateRequest createRequest = new CreateRequest(); CreateRequest createRequest = new CreateRequest();
// 商户订单号 // 商户订单号
createRequest.setOutTradeNo(orderNumber); createRequest.setOutTradeNo(orderNumber);
// 商户退款单号 // 商户退款单号
String outRefundNo = RefundUtils.generateRefundNo(); String outRefundNo = RefundUtils.generateRefundPartNo(orderItemsId);
createRequest.setOutRefundNo(outRefundNo); createRequest.setOutRefundNo(outRefundNo);
// 退款结果回调 // 退款结果回调
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback"); createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/part/callback");
// 退款金额 // 退款金额
AmountReq amountReq = new AmountReq(); AmountReq amountReq = new AmountReq();
BigDecimal refundAmount; BigDecimal refundAmount;
CouponSnapshot couponSnapshot = order.getCouponSnapshot(); CouponSnapshot couponSnapshot = order.getCouponSnapshot();
if (couponSnapshot == null) { if (couponSnapshot == null) {
refundAmount = amount; refundAmount = amount;
} else {
// 判断是否为最后一个商品如果是则将剩余金额全部退款
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 { } else {
BigDecimal couponAmount = couponSnapshot.getConditionAmount(); BigDecimal couponAmount = couponSnapshot.getConditionAmount();
BigDecimal totalAmount = order.getTotalAmount().add(couponAmount); BigDecimal totalAmount = order.getTotalAmount().add(couponAmount);
@ -269,6 +296,8 @@ public class WeChatServiceImpl implements WeChatService {
BigDecimal itemCouponRefund = itemShare.multiply(couponAmount); BigDecimal itemCouponRefund = itemShare.multiply(couponAmount);
refundAmount = amount.subtract(itemCouponRefund); refundAmount = amount.subtract(itemCouponRefund);
} }
}
refundAmount = refundAmount.movePointRight(2).setScale(0, RoundingMode.HALF_UP); refundAmount = refundAmount.movePointRight(2).setScale(0, RoundingMode.HALF_UP);
amountReq.setRefund(refundAmount.longValue()); amountReq.setRefund(refundAmount.longValue());
amountReq.setTotal(order.getTotalAmount().movePointRight(2).longValue()); amountReq.setTotal(order.getTotalAmount().movePointRight(2).longValue());
@ -325,6 +354,20 @@ public class WeChatServiceImpl implements WeChatService {
boolean save = refundRecordService.save(refundRecord); boolean save = refundRecordService.save(refundRecord);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "退款记录生成失败"); ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "退款记录生成失败");
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<>(); QueryWrapper<OrderItems> orderItemsQueryWrapper = new QueryWrapper<>();
orderItemsQueryWrapper.eq("orderId", order.getId()); orderItemsQueryWrapper.eq("orderId", order.getId());
@ -361,6 +404,9 @@ public class WeChatServiceImpl implements WeChatService {
ThrowUtils.throwIf(!updateBatch, ErrorCode.SYSTEM_ERROR, "商品库存恢复失败"); ThrowUtils.throwIf(!updateBatch, ErrorCode.SYSTEM_ERROR, "商品库存恢复失败");
System.out.println("---------------------------微信退款回调(结束)-------------------------------"); System.out.println("---------------------------微信退款回调(结束)-------------------------------");
}
return true; return true;
} }
@ -372,9 +418,49 @@ public class WeChatServiceImpl implements WeChatService {
*/ */
@Override @Override
public boolean refundPartCallback(RefundNotification refundNotification) { 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 { public class RefundUtils {
// 生成唯一的退款单号格式为 yyyyMMddHHmmssSSS + 随机数 // 生成唯一的全额退款单号格式为 yyyyMMddHHmmssSSS + 随机数
public static String generateRefundNo() { public static String generateRefundNo() {
// 获取当前时间的时间戳 // 获取当前时间的时间戳
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
@ -18,4 +18,36 @@ public class RefundUtils {
return timestamp + randomNum; 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;
}
} }