|
|
@@ -1,16 +1,26 @@
|
|
|
package shop.alien.dining.service.impl;
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
import shop.alien.dining.feign.AlienStoreFeign;
|
|
|
import shop.alien.dining.service.DiningCouponService;
|
|
|
+import shop.alien.dining.util.TokenUtil;
|
|
|
import shop.alien.entity.result.R;
|
|
|
+import shop.alien.entity.store.LifeDiscountCoupon;
|
|
|
+import shop.alien.entity.store.LifeDiscountCouponUser;
|
|
|
import shop.alien.entity.store.vo.LifeDiscountCouponVo;
|
|
|
+import shop.alien.mapper.LifeDiscountCouponMapper;
|
|
|
+import shop.alien.mapper.LifeDiscountCouponUserMapper;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 点餐模块-优惠券服务实现(透传 Feign 调 store,满足小程序我的优惠券/详情/选券)
|
|
|
@@ -25,6 +35,8 @@ import java.util.Map;
|
|
|
public class DiningCouponServiceImpl implements DiningCouponService {
|
|
|
|
|
|
private final AlienStoreFeign alienStoreFeign;
|
|
|
+ private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
|
|
|
+ private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
|
|
|
|
|
|
@Override
|
|
|
public R<List<LifeDiscountCouponVo>> getUserCouponList(String authorization, int page, int size, String tabType) {
|
|
|
@@ -70,4 +82,131 @@ public class DiningCouponServiceImpl implements DiningCouponService {
|
|
|
return R.fail("获取门店可用优惠券列表失败");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<List<LifeDiscountCouponVo>> getUserOwnedCoupons(String storeId, BigDecimal amount) {
|
|
|
+ log.info("查询用户拥有的优惠券, storeId={}, amount={}", storeId, amount);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取当前用户ID
|
|
|
+ Integer userId = TokenUtil.getCurrentUserId();
|
|
|
+ if (userId == null) {
|
|
|
+ return R.fail("用户未登录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询用户拥有的优惠券(未使用且未过期的)
|
|
|
+ LambdaQueryWrapper<LifeDiscountCouponUser> userWrapper = new LambdaQueryWrapper<>();
|
|
|
+ userWrapper.eq(LifeDiscountCouponUser::getUserId, userId);
|
|
|
+ userWrapper.eq(LifeDiscountCouponUser::getStatus, 0); // 0:待使用
|
|
|
+ userWrapper.eq(LifeDiscountCouponUser::getDeleteFlag, 0);
|
|
|
+ userWrapper.ge(LifeDiscountCouponUser::getExpirationTime, LocalDate.now()); // 未过期
|
|
|
+ List<LifeDiscountCouponUser> userCoupons = lifeDiscountCouponUserMapper.selectList(userWrapper);
|
|
|
+
|
|
|
+ if (userCoupons == null || userCoupons.isEmpty()) {
|
|
|
+ log.info("用户没有可用的优惠券, userId={}", userId);
|
|
|
+ return R.data(new ArrayList<>());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取优惠券ID列表
|
|
|
+ List<Integer> couponIds = userCoupons.stream()
|
|
|
+ .map(LifeDiscountCouponUser::getCouponId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 查询优惠券详情
|
|
|
+ LambdaQueryWrapper<LifeDiscountCoupon> couponWrapper = new LambdaQueryWrapper<>();
|
|
|
+ couponWrapper.in(LifeDiscountCoupon::getId, couponIds);
|
|
|
+ couponWrapper.eq(LifeDiscountCoupon::getDeleteFlag, 0);
|
|
|
+ if (StringUtils.hasText(storeId)) {
|
|
|
+ couponWrapper.eq(LifeDiscountCoupon::getStoreId, storeId);
|
|
|
+ }
|
|
|
+ List<LifeDiscountCoupon> coupons = lifeDiscountCouponMapper.selectList(couponWrapper);
|
|
|
+
|
|
|
+ if (coupons == null || coupons.isEmpty()) {
|
|
|
+ log.info("未找到优惠券详情, userId={}, couponIds={}", userId, couponIds);
|
|
|
+ return R.data(new ArrayList<>());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转换为VO并设置用户券ID
|
|
|
+ List<LifeDiscountCouponVo> couponVos = new ArrayList<>();
|
|
|
+ for (LifeDiscountCoupon coupon : coupons) {
|
|
|
+ // 找到对应的用户券
|
|
|
+ LifeDiscountCouponUser userCoupon = userCoupons.stream()
|
|
|
+ .filter(uc -> uc.getCouponId().equals(coupon.getId()))
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ if (userCoupon == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ LifeDiscountCouponVo vo = convertToVo(coupon, userCoupon);
|
|
|
+ couponVos.add(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序:符合支付条件的优先,其次优惠力度大的优先
|
|
|
+ if (amount != null) {
|
|
|
+ couponVos.sort((vo1, vo2) -> {
|
|
|
+ // 判断是否符合支付条件(满足最低消费要求)
|
|
|
+ boolean vo1CanUse = vo1.getMinimumSpendingAmount() == null
|
|
|
+ || vo1.getMinimumSpendingAmount().compareTo(amount) <= 0;
|
|
|
+ boolean vo2CanUse = vo2.getMinimumSpendingAmount() == null
|
|
|
+ || vo2.getMinimumSpendingAmount().compareTo(amount) <= 0;
|
|
|
+
|
|
|
+ // 第一优先级:符合支付条件的优先
|
|
|
+ if (vo1CanUse && !vo2CanUse) {
|
|
|
+ return -1; // vo1 排在前面
|
|
|
+ }
|
|
|
+ if (!vo1CanUse && vo2CanUse) {
|
|
|
+ return 1; // vo2 排在前面
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第二优先级:优惠力度大的优先(nominalValue 大的)
|
|
|
+ BigDecimal nominalValue1 = vo1.getNominalValue() != null ? vo1.getNominalValue() : BigDecimal.ZERO;
|
|
|
+ BigDecimal nominalValue2 = vo2.getNominalValue() != null ? vo2.getNominalValue() : BigDecimal.ZERO;
|
|
|
+ return nominalValue2.compareTo(nominalValue1); // 降序排列
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 如果没有提供金额,只按优惠力度排序
|
|
|
+ couponVos.sort((vo1, vo2) -> {
|
|
|
+ BigDecimal nominalValue1 = vo1.getNominalValue() != null ? vo1.getNominalValue() : BigDecimal.ZERO;
|
|
|
+ BigDecimal nominalValue2 = vo2.getNominalValue() != null ? vo2.getNominalValue() : BigDecimal.ZERO;
|
|
|
+ return nominalValue2.compareTo(nominalValue1); // 降序排列
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("查询用户拥有的优惠券成功, userId={}, count={}", userId, couponVos.size());
|
|
|
+ return R.data(couponVos);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询用户拥有的优惠券失败: {}", e.getMessage(), e);
|
|
|
+ return R.fail("查询用户拥有的优惠券失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将优惠券实体转换为VO
|
|
|
+ */
|
|
|
+ private LifeDiscountCouponVo convertToVo(LifeDiscountCoupon coupon, LifeDiscountCouponUser userCoupon) {
|
|
|
+ LifeDiscountCouponVo vo = new LifeDiscountCouponVo();
|
|
|
+ vo.setId(coupon.getId());
|
|
|
+ vo.setUserCouponId(userCoupon.getId());
|
|
|
+ vo.setStoreId(coupon.getStoreId());
|
|
|
+ vo.setUserId(String.valueOf(userCoupon.getUserId()));
|
|
|
+ vo.setCouponId(coupon.getId());
|
|
|
+ vo.setName(coupon.getName());
|
|
|
+ vo.setNominalValue(coupon.getNominalValue());
|
|
|
+ vo.setExpirationDate(coupon.getExpirationDate());
|
|
|
+ vo.setStartDate(coupon.getStartDate());
|
|
|
+ vo.setEndDate(coupon.getEndDate());
|
|
|
+ vo.setSingleQty(coupon.getSingleQty());
|
|
|
+ vo.setSupplementaryInstruction(coupon.getSupplementaryInstruction());
|
|
|
+ vo.setGetStatus(coupon.getGetStatus());
|
|
|
+ vo.setRestrictedQuantity(coupon.getRestrictedQuantity());
|
|
|
+ vo.setMinimumSpendingAmount(coupon.getMinimumSpendingAmount());
|
|
|
+ vo.setType(coupon.getType());
|
|
|
+ vo.setAttentionCanReceived(coupon.getAttentionCanReceived());
|
|
|
+ vo.setExpirationTime(userCoupon.getExpirationTime());
|
|
|
+ vo.setCreatedTime(coupon.getCreatedTime());
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
}
|