订单 优惠券部分 重写

This commit is contained in:
wangw 2025-09-17 10:54:47 +08:00
parent b4fb2afd68
commit de08266971
14 changed files with 588 additions and 407 deletions

View File

@ -98,6 +98,11 @@ public class OrderDetailDTO implements Serializable {
*/
private BigDecimal couponNum;
/**
* 半价券抵扣数量
*/
private BigDecimal halfPriceCouponNum;
/**
* 退菜数量不管价格
*/

View File

@ -97,6 +97,10 @@ admin-app APP管理端 APP+雪花ID
* 满减优惠券抵扣金额
*/
private BigDecimal fullCouponDiscountAmount;
/**
* 其它优惠券抵扣金额
*/
private BigDecimal otherCouponDiscountAmount;
/**
* 手动优惠金额

View File

@ -1,10 +1,14 @@
package com.czg.market.service;
import com.czg.account.vo.UserCouponVo;
import com.czg.market.dto.ShopCouponDTO;
import com.czg.market.entity.MkShopCouponRecord;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.ShopCoupon;
import java.util.List;
/**
* 优惠券信息表 服务层
*
@ -13,10 +17,20 @@ import com.czg.market.entity.ShopCoupon;
*/
public interface ShopCouponService extends IService<ShopCoupon> {
Page<ShopCouponDTO> getCouponPage(ShopCouponDTO param);
ShopCouponDTO getCouponById(Long id);
void addCoupon(ShopCouponDTO param);
void updateCouponById(ShopCouponDTO param);
void deleteCoupon(Long id);
Page<MkShopCouponRecord> find(Long userId, Long shopId, Integer status);
List<UserCouponVo> findCoupon(Long shopId, Long shopUserId, Integer type);
Boolean use(List<Long> ids, Long shopUserId, Long orderId);
Boolean refund(Long orderId, Long shopUserId);
}

View File

@ -51,7 +51,7 @@ public class CheckOrderPay implements Serializable {
/**
* 折扣比例(计算时 向上取整保留 两位小数)
*/
private BigDecimal discountRatio;
// private BigDecimal discountRatio;
/**
* 手动优惠金额
*/
@ -62,9 +62,9 @@ public class CheckOrderPay implements Serializable {
*/
private BigDecimal productCouponDiscountAmount;
/**
* 满减优惠券抵扣金额
* 其它优惠券抵扣金额
*/
private BigDecimal fullCouponDiscountAmount;
private BigDecimal otherCouponDiscountAmount;
/**
* 用户使用的卡券
*/
@ -108,15 +108,15 @@ public class CheckOrderPay implements Serializable {
return pointsNum == null ? 0 : pointsNum;
}
public BigDecimal getDiscountRatio() {
if (discountRatio == null) {
return BigDecimal.ZERO;
}
return discountRatio.setScale(2, RoundingMode.UP);
}
// public BigDecimal getDiscountRatio() {
// if (discountRatio == null) {
// return BigDecimal.ZERO;
// }
// return discountRatio.setScale(2, RoundingMode.UP);
// }
public BigDecimal getFullCouponDiscountAmount() {
return fullCouponDiscountAmount == null ? BigDecimal.ZERO : fullCouponDiscountAmount;
public BigDecimal getOtherCouponDiscountAmount() {
return otherCouponDiscountAmount == null ? BigDecimal.ZERO : otherCouponDiscountAmount;
}
public BigDecimal getProductCouponDiscountAmount() {

View File

@ -102,6 +102,10 @@ public class OrderDetail implements Serializable {
* 优惠券抵扣数量
*/
private BigDecimal couponNum;
/**
* 半价券抵扣数量
*/
private BigDecimal halfPriceCouponNum;
/**
* 退菜数量不管价格

View File

@ -102,6 +102,10 @@ public class OrderInfo implements Serializable {
* 满减优惠券抵扣金额
*/
private BigDecimal fullCouponDiscountAmount;
/**
* 其它优惠券抵扣金额
*/
private BigDecimal otherCouponDiscountAmount;
/**
* 折扣金额

View File

@ -17,7 +17,6 @@ import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* 订单表 服务层
@ -50,12 +49,8 @@ public interface OrderInfoService extends IService<OrderInfo> {
void expired(Long orderId);
OrderInfo createPayOrder(Long shopId, BigDecimal amount, String remark);
void processOrderDetails2(List<OrderDetail> orderDetails, Map<Long, Integer> prodCouponMap,
BigDecimalDTO prodCouponAmount, BigDecimalDTO totalAmount, BigDecimalDTO packAmount,
boolean isAllPack, Integer userAllPack, boolean isVipPrice);
void getOrderAmount(List<OrderDetail> orderDetails, BigDecimalDTO totalAmount, BigDecimalDTO packAmount,
BigDecimalDTO tempAmount, boolean isAllPack, Integer userAllPack, boolean isVipPrice);
Boolean printOrder(Long shopId, OrderInfoPrintDTO orderInfoPrintDTO);

View File

@ -2,6 +2,8 @@ package com.czg.utils;
import cn.hutool.core.util.StrUtil;
import java.time.LocalDate;
/**
* @author ww
* @description
@ -15,4 +17,18 @@ public class CzgStrUtils {
public static String getStrOrNull(String str) {
return StrUtil.isNotBlank(str) ? str : null;
}
/**
* 获取当天是周几
* @return 周几
*/
public static String getStrWeek() {
int dayOfWeek = LocalDate.now().getDayOfWeek().getValue();
// 定义汉字星期数组索引0不用从1开始对应周一到周日
String[] chineseWeeks = {"", "", "", "", "", "", "", ""};
return "" + chineseWeeks[dayOfWeek];
}
}

View File

@ -1,216 +0,0 @@
//package com.czg.service.account.service.impl;
//
//import cn.hutool.core.bean.BeanUtil;
//import cn.hutool.core.collection.CollectionUtil;
//import cn.hutool.core.date.DateUtil;
//import cn.hutool.core.exceptions.ValidateException;
//import cn.hutool.core.util.StrUtil;
//import com.alibaba.fastjson2.JSONObject;
//import com.czg.account.dto.QueryReceiveDto;
//import com.czg.account.entity.ShopActivateCouponRecord;
//import com.czg.account.entity.ShopUser;
//import com.czg.account.service.ShopActivateCouponRecordService;
//import com.czg.account.service.ShopInfoService;
//import com.czg.account.service.ShopUserService;
//import com.czg.account.vo.CouponReceiveVo;
//import com.czg.account.vo.UserCouponVo;
//import com.czg.product.entity.Product;
//import com.czg.product.service.ProductService;
//import com.czg.utils.PageUtil;
//import com.github.pagehelper.PageHelper;
//import com.github.pagehelper.PageInfo;
//import com.mybatisflex.core.paginate.Page;
//import com.mybatisflex.spring.service.impl.ServiceImpl;
//import jakarta.annotation.Resource;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.dubbo.config.annotation.DubboReference;
//import org.apache.dubbo.config.annotation.DubboService;
//
//import java.math.BigDecimal;
//import java.time.LocalTime;
//import java.time.format.DateTimeFormatter;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * 优惠券 服务层实现
// *
// * @author ww
// * @since 2025-02-17
// */
//@Slf4j
//@DubboService
//public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCoupon> implements ShopCouponService {
//
// @Resource
// private ShopActivateCouponRecordService couponRecordService;
// @Resource
// private ShopUserService shopUserService;
// @Resource
// private ShopInfoService shopInfoService;
// @DubboReference
// private ProductService productService;
//
// @Override
// public List<ShopCouponDTO> getList(Long shopId, Integer type, Integer status) {
// List<ShopCouponDTO> coupons = queryChain().select()
// .eq(ShopCoupon::getShopId, shopId)
// .eq(ShopCoupon::getType, type)
// .eq(ShopCoupon::getStatus, status)
// .orderBy(ShopCoupon::getCreateTime).desc()
// .listAs(ShopCouponDTO.class);
// System.out.println(coupons);
// coupons.forEach(coupon -> {
// if (coupon.getProId() != null) {
// Product product = productService.getById(coupon.getProId());
// coupon.setProName(product.getName());
// }
// });
// return coupons;
// }
//
// @Override
// public Boolean add(ShopCouponDTO couponDTO) {
// ShopCoupon shopCoupon = new ShopCoupon();
// BeanUtil.copyProperties(couponDTO, shopCoupon);
// shopCoupon.setLeftNumber(shopCoupon.getNumber());
// return save(shopCoupon);
// }
//
// @Override
// public Boolean edit(ShopCouponDTO couponDTO) {
// ShopCoupon shopCoupon = new ShopCoupon();
// BeanUtil.copyProperties(couponDTO, shopCoupon);
// if (couponDTO.getNumber() != null) {
// ShopCoupon tbShopCoupon = getById(couponDTO.getId());
// if (shopCoupon.getNumber() < tbShopCoupon.getNumber()) {
// throw new ValidateException("修改失败 发放数量不可减少");
// } else {
// shopCoupon.setLeftNumber(shopCoupon.getLeftNumber() + shopCoupon.getNumber() - tbShopCoupon.getNumber());
// }
// }
// return updateById(shopCoupon);
// }
//
// @Override
// public Page<CouponReceiveVo> queryReceive(QueryReceiveDto param) {
// Page<Object> page = PageUtil.buildPage();
// PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize()));
// return PageUtil.convert(new PageInfo<>(couponRecordService.queryReceive(param)));
// }
//
//
// @Override
// public Page<ShopActivateCouponRecord> find(Long userId, Long shopId, Integer status) {
// Page<Object> page = PageUtil.buildPage();
// List<Long> shopUserIds = shopUserService.queryChain()
// .eq(ShopUser::getUserId, userId)
// .eq(ShopUser::getShopId, shopId)
// .select(ShopUser::getId).listAs(Long.class);
// if (CollectionUtil.isNotEmpty(shopUserIds)) {
// PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize()));
// return PageUtil.convert(new PageInfo<>(couponRecordService.findByUser(shopUserIds, status)));
// }
// return new Page<>();
// }
//
// @Override
// public List<UserCouponVo> findCoupon(Long shopId, Long shopUserId, Integer type) {
// List<UserCouponVo> tbUserCouponVos = couponRecordService.queryByVipIdAndShopId(shopId, shopUserId, type);
// if (CollectionUtil.isNotEmpty(tbUserCouponVos)) {
// String week = DateUtil.dayOfWeekEnum(new Date()).toChinese("");
// LocalTime now = LocalTime.now();
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
//
// //券id 券使用描述
// Map<Long, JSONObject> coupons = new HashMap<>();
// for (UserCouponVo tbUserCouponVo : tbUserCouponVos) {
// if (!coupons.containsKey(tbUserCouponVo.getCouponId())) {
// setCouponInfo(coupons, tbUserCouponVo, null, week, now, formatter);
// }
// JSONObject couponJson = coupons.get(tbUserCouponVo.getCouponId());
// tbUserCouponVo.setUseRestrictions(couponJson.getString("useRestrictions"));
// tbUserCouponVo.setUse(couponJson.getBoolean("isUse"));
//
// }
// tbUserCouponVos.sort(Comparator.comparing(UserCouponVo::isUse).reversed());
// return tbUserCouponVos;
// }
// return null;
// }
//
// @Override
// public Boolean use(List<Long> ids, Long shopUserId, Long orderId) {
// List<ShopActivateCouponRecord> records = couponRecordService.listByIds(ids);
// if (records.isEmpty()) {
// log.error("优惠券使用失败订单Id:{}", orderId);
// return false;
// }
// // 使用流来统计 couponId 出现的次数
// Map<Long, Long> couponIdCountMap = records.stream()
// .collect(Collectors.groupingBy(ShopActivateCouponRecord::getCouponId,
// Collectors.counting()
// ));
// couponIdCountMap.forEach((couponId, count) -> {
// ShopCoupon tbShopCoupon = getById(couponId);
// tbShopCoupon.setUseNumber(tbShopCoupon.getUseNumber() + count.intValue());
// ShopCoupon coupon1 = new ShopCoupon();
// coupon1.setId(couponId);
// coupon1.setUseNumber(tbShopCoupon.getUseNumber());
// updateById(coupon1);
// });
// return couponRecordService.updateChain()
// .set(ShopActivateCouponRecord::getStatus, 1)
// .set(ShopActivateCouponRecord::getTargetId, orderId)
// .eq(ShopActivateCouponRecord::getShopUserId, shopUserId)
// .in(ShopActivateCouponRecord::getId, ids).update();
// }
//
// /**
// * 退还券
// */
// @Override
// public Boolean refund(Long orderId, Long shopUserId) {
// return couponRecordService.updateChain()
// .set(ShopActivateCouponRecord::getStatus, 0)
// .eq(ShopActivateCouponRecord::getShopUserId, shopUserId)
// .eq(ShopActivateCouponRecord::getTargetId, orderId)
// .update();
// }
//
// private void setCouponInfo(Map<Long, JSONObject> coupons, UserCouponVo tbUserCouponVo, BigDecimal amount, String week, LocalTime now, DateTimeFormatter formatter) {
// JSONObject json = new JSONObject();
// boolean isUse = true;
// ShopCoupon tbShopCoupon = getById(tbUserCouponVo.getCouponId());
// StringBuilder useRestrictions = new StringBuilder("每天 ");
// if (amount != null && tbShopCoupon.getType().equals(1)) {
// if (amount.compareTo(tbShopCoupon.getFullAmount()) < 0) {
// isUse = false;
// }
// }
// if (StrUtil.isNotBlank(tbShopCoupon.getUserDays())) {
// String[] split = tbShopCoupon.getUserDays().split(",");
// if (split.length != 7) {
// useRestrictions = new StringBuilder(STR."\{tbShopCoupon.getUserDays()} ");
// }
// if (!tbShopCoupon.getUserDays().contains(week)) {
// isUse = false;
// }
// }
// if ("custom".equals(tbShopCoupon.getUseTimeType())) {
// if (now.isBefore(tbShopCoupon.getUseStartTime()) || now.isAfter(tbShopCoupon.getUseEndTime())) {
// isUse = false;
// }
// useRestrictions.append(
// STR."\{tbShopCoupon.getUseStartTime().format(formatter)}-\{tbShopCoupon.getUseEndTime().format(formatter)}");
// } else {
// useRestrictions.append("全时段");
// }
// useRestrictions.append(" 可用");
// json.put("isUse", isUse);
// json.put("useRestrictions", useRestrictions);
//
// coupons.put(tbUserCouponVo.getCouponId(), json);
// }
//
//}

View File

@ -14,5 +14,18 @@
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
<compilerArgs>--enable-preview</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,30 +1,62 @@
package com.czg.service.market.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.account.entity.ShopUser;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.ShopUserService;
import com.czg.account.vo.UserCouponVo;
import com.czg.market.dto.ShopCouponDTO;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.entity.ShopCoupon;
import com.czg.market.service.MkCouponGiftService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.product.service.ProductService;
import com.czg.service.market.mapper.ShopCouponMapper;
import com.czg.utils.AssertUtil;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import static java.lang.StringTemplate.STR;
/**
* 优惠券信息表 服务层实现
*
* @author ww
* @since 2025-09-11
*/
@Slf4j
@DubboService
public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCoupon> implements ShopCouponService {
@Resource
private MkCouponGiftService couponGiftService;
@Resource
private MkShopCouponRecordService recordService;
@Resource
private ShopUserService shopUserService;
@Resource
private ShopInfoService shopInfoService;
@DubboReference
private ProductService productService;
@Override
public Page<ShopCouponDTO> getCouponPage(ShopCouponDTO param) {
@ -81,4 +113,129 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
updateById(new ShopCoupon().setIsDel(1).setId(id), true);
couponGiftService.deleteJoinCouponGift(id, 3);
}
@Override
public Page<MkShopCouponRecord> find(Long userId, Long shopId, Integer status) {
Page<Object> page = PageUtil.buildPage();
List<Long> shopUserIds = shopUserService.queryChain()
.eq(ShopUser::getUserId, userId)
.eq(ShopUser::getShopId, shopId)
.select(ShopUser::getId).listAs(Long.class);
if (CollectionUtil.isNotEmpty(shopUserIds)) {
PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize()));
return PageUtil.convert(new PageInfo<>(recordService.findByUser(shopUserIds, status)));
}
return new Page<>();
}
@Override
public List<UserCouponVo> findCoupon(Long shopId, Long shopUserId, Integer type) {
List<UserCouponVo> tbUserCouponVos = recordService.queryByVipIdAndShopId(shopId, shopUserId, type);
if (CollectionUtil.isNotEmpty(tbUserCouponVos)) {
String week = DateUtil.dayOfWeekEnum(new Date()).toChinese("");
LocalTime now = LocalTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
//券id 券使用描述
Map<Long, JSONObject> coupons = new HashMap<>();
for (UserCouponVo tbUserCouponVo : tbUserCouponVos) {
if (!coupons.containsKey(tbUserCouponVo.getCouponId())) {
setCouponInfo(coupons, tbUserCouponVo, null, week, now, formatter);
}
JSONObject couponJson = coupons.get(tbUserCouponVo.getCouponId());
tbUserCouponVo.setUseRestrictions(couponJson.getString("useRestrictions"));
tbUserCouponVo.setUse(couponJson.getBoolean("isUse"));
}
tbUserCouponVos.sort(Comparator.comparing(UserCouponVo::isUse).reversed());
return tbUserCouponVos;
}
return null;
}
@Override
public Boolean use(List<Long> ids, Long shopUserId, Long orderId) {
List<MkShopCouponRecord> records = recordService.listByIds(ids);
if (records.isEmpty()) {
log.error("优惠券使用失败订单Id:{}", orderId);
return false;
}
// 使用流来统计 couponId 出现的次数
Map<Long, Long> couponIdCountMap = records.stream()
.collect(Collectors.groupingBy(MkShopCouponRecord::getCouponId,
Collectors.counting()
));
couponIdCountMap.forEach((couponId, count) -> {
ShopCoupon tbShopCoupon = getById(couponId);
tbShopCoupon.setUseNum(tbShopCoupon.getUseNum() + count.intValue());
ShopCoupon coupon1 = new ShopCoupon();
coupon1.setId(couponId);
coupon1.setUseNum(tbShopCoupon.getUseNum());
updateById(coupon1);
});
return recordService.updateChain()
.set(MkShopCouponRecord::getStatus, 1)
.set(MkShopCouponRecord::getTargetId, orderId)
.eq(MkShopCouponRecord::getShopUserId, shopUserId)
.in(MkShopCouponRecord::getId, ids).update();
}
/**
* 退还券
*/
@Override
public Boolean refund(Long orderId, Long shopUserId) {
return recordService.updateChain()
.set(MkShopCouponRecord::getStatus, 0)
.eq(MkShopCouponRecord::getShopUserId, shopUserId)
.eq(MkShopCouponRecord::getTargetId, orderId)
.update();
}
private void setCouponInfo(Map<Long, JSONObject> coupons, UserCouponVo tbUserCouponVo, BigDecimal amount, String week, LocalTime now, DateTimeFormatter formatter) {
JSONObject json = new JSONObject();
boolean isUse = true;
ShopCoupon tbShopCoupon = getById(tbUserCouponVo.getCouponId());
StringBuilder useRestrictions = new StringBuilder("每天 ");
if (amount != null && tbShopCoupon.getCouponType().equals(1)) {
if (amount.compareTo(tbShopCoupon.getFullAmount()) < 0) {
isUse = false;
}
}
if (StrUtil.isNotBlank(tbShopCoupon.getUseDays())) {
String[] split = tbShopCoupon.getUseDays().split(",");
if (split.length != 7) {
useRestrictions = new StringBuilder(STR."\{tbShopCoupon.getUseDays()} ");
}
if (!tbShopCoupon.getUseDays().contains(week)) {
isUse = false;
}
}
if ("custom".equals(tbShopCoupon.getUseTimeType())) {
LocalTime currentTime = LocalTime.now();
LocalTime startTime = tbShopCoupon.getUseStartTime().toLocalTime();
LocalTime endTime = tbShopCoupon.getUseEndTime().toLocalTime();
if (currentTime.isBefore(startTime)) {
if (startTime.isBefore(endTime)) {
isUse = false;
} else if (currentTime.isAfter(endTime)) {
isUse = false;
}
} else if (startTime.isBefore(endTime)) {
if (currentTime.isAfter(endTime)) {
isUse = false;
}
}
useRestrictions.append(
STR."\{startTime.format(formatter)}-\{endTime.format(formatter)}");
} else {
useRestrictions.append("全时段");
}
useRestrictions.append(" 可用");
json.put("isUse", isUse);
json.put("useRestrictions", useRestrictions);
coupons.put(tbUserCouponVo.getCouponId(), json);
}
}

View File

@ -46,6 +46,7 @@
<if test="status != null">
and mk_shop_coupon_record.status = #{status}
</if>
and mk_shop_coupon_record.is_del = 0
order by mk_shop_coupon_record.status , mk_shop_coupon_record.create_time desc
</select>
@ -78,6 +79,7 @@
and inRecord.status = 0
and inRecord.use_start_time &lt; now()
and inRecord.use_end_time &gt; now()
and inRecord.is_del = 0
order by inRecord.use_end_time
</select>
</mapper>

View File

@ -21,7 +21,11 @@ import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.ApiNotPrintException;
import com.czg.exception.CzgException;
import com.czg.exception.OrderCancelException;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.entity.ShopCoupon;
import com.czg.market.service.MemberOrderService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.market.service.TbMemberConfigService;
import com.czg.order.dto.*;
import com.czg.order.entity.*;
@ -56,10 +60,12 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
@ -101,12 +107,14 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
private ShopUserFlowService flowService;
@DubboReference
private ShopTableService shopTableService;
// @DubboReference
// @DubboReference
// private ShopActivateService activateService;
@DubboReference
private PointsBasicSettingService pointsBasicService;
// @DubboReference
// private ShopCouponService couponService;
@DubboReference
private ShopCouponService couponService;
@DubboReference
private MkShopCouponRecordService couponRecordService;
@DubboReference
private TbMemberConfigService memberConfigService;
@Resource
@ -339,70 +347,149 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
}
orderInfo.setUserId(userInfo.getId());
}
if (param.getDiscountRatio().compareTo(BigDecimal.ZERO) < 0 || param.getDiscountRatio().compareTo(BigDecimal.ONE) > 0) {
throw new ValidateException("生成支付订单失败,折扣比例不正确");
}
//商品券 <商品id数量>
Map<Long, Integer> prodCouponMap = new HashMap<>();
//满减券 满fullCouponAmount 减disCouponAmount
BigDecimalDTO fullAmount = new BigDecimalDTO(BigDecimal.ZERO);
BigDecimalDTO discountAmount = new BigDecimalDTO(BigDecimal.ZERO);
//校验优惠券
checkCoupon(prodCouponMap, fullAmount, discountAmount, param);
//获取商品信息 计算金额 需要传入优惠券 减去优惠券
List<OrderDetail> orderDetails = orderDetailService.queryChain().eq(OrderDetail::getOrderId, param.getOrderId()).select().list();
//商品优惠券金额
BigDecimalDTO prodCouponAmount = new BigDecimalDTO(BigDecimal.ZERO);
//总商品支付金额 不包含打包费 用来计算后续
//总商品金额 不包含打包费 不包含临时菜
BigDecimalDTO totalAmount = new BigDecimalDTO(BigDecimal.ZERO);
//最终打包费
BigDecimalDTO packAmount = new BigDecimalDTO(BigDecimal.ZERO);
processOrderDetails2(orderDetails, prodCouponMap, prodCouponAmount, totalAmount, packAmount, param.isAllPack(), param.getUserAllPack(), param.isVipPrice());
//临时菜总费用
BigDecimalDTO tempAmount = new BigDecimalDTO(BigDecimal.ZERO);
//商品兑换券金额
BigDecimalDTO prodCouponAmount = new BigDecimalDTO(BigDecimal.ZERO);
//买一送一券金额
BigDecimalDTO oneGiftAmount = new BigDecimalDTO(BigDecimal.ZERO);
//第二件半价券金额
BigDecimalDTO twoHalfAmount = new BigDecimalDTO(BigDecimal.ZERO);
//折扣金额
BigDecimalDTO rateAmount = new BigDecimalDTO(BigDecimal.ZERO);
//满减金额
BigDecimalDTO fullReductionAmount = new BigDecimalDTO(BigDecimal.ZERO);
getOrderAmount(orderDetails, totalAmount, packAmount, tempAmount,
param.isAllPack(), param.getUserAllPack(), param.isVipPrice());
if (totalAmount.getPrice().compareTo(param.getOriginAmount()) != 0) {
log.info("订单原价不正确:订单原价:{},传递为:{}", totalAmount.getPrice(), param.getOriginAmount());
throw new ValidateException("生成支付订单失败,订单原金额不正确");
}
//优惠券部分 目前规则 每个券只能用一张
if (CollUtil.isNotEmpty(param.getCouponList())) {
QueryWrapper couponRecordQuery = new QueryWrapper();
couponRecordQuery.in(MkShopCouponRecord::getId, param.getCouponList());
couponRecordQuery.eq(MkShopCouponRecord::getShopId, shopId);
couponRecordQuery.gt(MkShopCouponRecord::getUseStartTime, LocalDateTime.now());
couponRecordQuery.le(MkShopCouponRecord::getUseEndTime, LocalDateTime.now());
couponRecordQuery.eq(MkShopCouponRecord::getStatus, 0);
couponRecordQuery.ne(MkShopCouponRecord::getIsDel, 1);
List<MkShopCouponRecord> list = couponRecordService.list(couponRecordQuery);
if (CollUtil.isEmpty(list) || param.getCouponList().size() != list.size()) {
throw new ValidateException("生成支付订单失败,优惠券不可用");
}
Map<Integer, MkShopCouponRecord> couponRecordMap = list.stream().collect(Collectors.toMap(MkShopCouponRecord::getType, t -> t));
AtomicBoolean otherCouponShare = new AtomicBoolean(true);
couponRecordMap.forEach((type, record) -> {
//1-满减券2-商品兑换券3-折扣券4-第二件半价券 6-买一送一券
// 7-固定价格券8-免配送费券 暂时没有
if (type == 2) {//商品券
ShopCoupon coupon = checkCoupon(record, param.isVipPrice());
if (coupon.getOtherCouponShare() != 1) {
otherCouponShare.set(false);
}
if (coupon.getFullAmount().compareTo(totalAmount.getPrice()) > 0) {
throw new ValidateException("生成支付订单失败,商品券:" + coupon + " 未达到使用门槛" + coupon.getFullAmount() + "");
}
boolean isAllFoods = true;
List<Long> couponFoodIds = new ArrayList<>();
if (StrUtil.isNotBlank(coupon.getFoods()) && !",".equals(coupon.getFoods())) {
couponFoodIds = Arrays.stream(coupon.getFoods().split(",")).map(Long::parseLong).toList();
}
foodsCalculate(orderDetails, isAllFoods, couponFoodIds, coupon.getDiscountNum(), "price_asc".equals(coupon.getUseRule()), prodCouponAmount);
} else if (type == 4 || type == 6) {//4-第二件半价券 6-买一送一券
if (!otherCouponShare.get()) {
throw new ValidateException("生成支付订单失败,商品券与其它券不可共用");
}
ShopCoupon coupon = checkCoupon(record, param.isVipPrice());
boolean isAllFoods = true;
List<Long> couponFoodIds = new ArrayList<>();
if (StrUtil.isNotBlank(coupon.getFoods()) && !",".equals(coupon.getFoods())) {
couponFoodIds = Arrays.stream(coupon.getFoods().split(",")).map(Long::parseLong).toList();
}
if (type == 6) {
oneGiftCalculate(orderDetails, isAllFoods, couponFoodIds, "price_asc".equals(coupon.getUseRule()), oneGiftAmount);
} else {
twoHalfCalculate(orderDetails, isAllFoods, couponFoodIds, "price_asc".equals(coupon.getUseRule()), twoHalfAmount);
}
} else if (type == 1 || type == 3) {//1-满减券 3-折扣券
if (!otherCouponShare.get()) {
throw new ValidateException("生成支付订单失败,商品券与其它券不可共用");
}
ShopCoupon coupon = checkCoupon(record, param.isVipPrice());
//计算门槛
boolean isAllFoods = true;
List<Long> couponFoodIds = new ArrayList<>();
if (StrUtil.isNotBlank(coupon.getFoods()) && !",".equals(coupon.getFoods())) {
couponFoodIds = Arrays.stream(coupon.getFoods().split(",")).map(Long::parseLong).toList();
}
thresholdCalculate(orderDetails, isAllFoods, couponFoodIds, coupon.getFullAmount());
if (type == 3) {
BigDecimal rate = new BigDecimal(record.getDiscountRate());
rateAmount.setPrice(rate.multiply(totalAmount.getPrice().subtract(tempAmount.getPrice()).subtract(prodCouponAmount.getPrice())).setScale(2, RoundingMode.DOWN));
if (rateAmount.getPrice().compareTo(coupon.getMaxDiscountAmount()) > 0) {
rateAmount.setPrice(coupon.getMaxDiscountAmount());
}
} else {
fullReductionAmount.setPrice(record.getDiscountAmount());
}
}
});
}
//总商品支付金额 不包含打包费 用来计算后续
if (prodCouponAmount.getPrice().compareTo(param.getProductCouponDiscountAmount()) != 0) {
log.info("支付计算金额不正确:商品券抵扣金额为:{},传递为:{}", prodCouponAmount.getPrice(), param.getProductCouponDiscountAmount());
throw new ValidateException("生成支付订单失败,商品优惠券优惠金额不正确");
}
// orderInfo.setOriginAmount(totalAmount.getPrice().add(packAmount.getPrice()).add(orderInfo.getSeatAmount()));
orderInfo.setOriginAmount(param.getOriginAmount());
BigDecimal newTotalAmount = totalAmount.getPrice();
//折扣金额 9折 计算 订单金额*0.9 向上取整
if (param.getDiscountRatio().compareTo(BigDecimal.ZERO) > 0) {
newTotalAmount = totalAmount.getPrice().multiply(param.getDiscountRatio()).setScale(2, RoundingMode.UP);
} else if (param.getDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
//减去商品优惠券
newTotalAmount = newTotalAmount.subtract(prodCouponAmount.getPrice());
//减去其它优惠券金额
newTotalAmount = newTotalAmount.subtract(fullReductionAmount.getPrice());
newTotalAmount = newTotalAmount.subtract(rateAmount.getPrice());
newTotalAmount = newTotalAmount.subtract(oneGiftAmount.getPrice());
newTotalAmount = newTotalAmount.subtract(twoHalfAmount.getPrice());
if (param.getOriginAmount().subtract(param.getProductCouponDiscountAmount()).subtract(param.getOtherCouponDiscountAmount()).compareTo(newTotalAmount) != 0) {
log.info("其它优惠券金额不正确:满减金额为:{},折扣金额为:{},买一赠一金额为:{},第二件半价券金额为:{} 传递为:{}",
fullReductionAmount.getPrice(), rateAmount.getPrice(), oneGiftAmount.getPrice(), twoHalfAmount.getPrice(), param.getOtherCouponDiscountAmount());
throw new ValidateException("生成支付订单失败,商品优惠券优惠金额不正确");
}
//TODO 新客立减
//折扣金额
if (param.getDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
newTotalAmount = totalAmount.getPrice().subtract(param.getDiscountAmount());
}
//满减券 校验
if (newTotalAmount.compareTo(fullAmount.getPrice()) < 0) {
throw new ValidateException("生成支付订单失败,满减券不满足条件");
}
//减去满减优惠券
newTotalAmount = newTotalAmount.subtract(discountAmount.getPrice());
//积分抵扣 金额范围校验 抵扣金额校验
// if (param.getPointsNum() > 0) {
// if (pointSetting.getMinPaymentAmount().compareTo(newTotalAmount) > 0) {
// throw new ValidateException("生成支付订单失败,未满足积分抵扣最低门槛");
// }
// if (pointSetting.getMaxDeductionRatio().multiply(newTotalAmount).compareTo(param.getPointsDiscountAmount()) < 0) {
// throw new ValidateException("生成支付订单失败,积分抵扣金额已超出最大抵扣金额");
// }
// BigDecimal pointAmount = new BigDecimal(param.getPointsNum()).divide(new BigDecimal(pointSetting.getEquivalentPoints()), 2, RoundingMode.DOWN);
// if (pointAmount.compareTo(param.getPointsDiscountAmount()) != 0) {
// throw new ValidateException("生成支付订单失败,积分抵扣金额不正确");
// }
// }
if (param.getPointsNum() > 0) {
if (pointSetting.getMinPaymentAmount().compareTo(newTotalAmount) > 0) {
throw new ValidateException("生成支付订单失败,未满足积分抵扣最低门槛");
}
if (pointSetting.getMaxDeductionRatio().multiply(newTotalAmount).compareTo(param.getPointsDiscountAmount()) < 0) {
throw new ValidateException("生成支付订单失败,积分抵扣金额已超出最大抵扣金额");
}
BigDecimal pointAmount = new BigDecimal(param.getPointsNum()).divide(new BigDecimal(pointSetting.getEquivalentPoints()), 2, RoundingMode.DOWN);
if (pointAmount.compareTo(param.getPointsDiscountAmount()) != 0) {
throw new ValidateException("生成支付订单失败,积分抵扣金额不正确");
}
}
newTotalAmount = newTotalAmount.subtract(param.getPointsDiscountAmount());
//抹零
newTotalAmount = newTotalAmount.subtract(param.getRoundAmount());
//校验最终金额订单金额 (扣除各类折扣)+打包费 餐位费
newTotalAmount = newTotalAmount.add(packAmount.getPrice()).add(orderInfo.getSeatAmount());
if (newTotalAmount.compareTo(param.getOrderAmount()) != 0) {
log.info("支付计算金额不正确订单Id:{},最终计算金额为:{},打包费:{},餐位费:{},商品券金额:{},满减券金额:{},积分抵扣金额:{},抹零金额:{}",
orderInfo.getId(), newTotalAmount, packAmount.getPrice(), orderInfo.getSeatAmount(), param.getProductCouponDiscountAmount(),
discountAmount.getPrice(), param.getPointsDiscountAmount(), param.getRoundAmount());
log.info("支付计算金额不正确订单Id:{},最终计算金额为:{},打包费:{},餐位费:{},积分抵扣金额:{},抹零金额:{}",
orderInfo.getId(), newTotalAmount, packAmount.getPrice(), orderInfo.getSeatAmount(),
param.getPointsDiscountAmount(), param.getRoundAmount());
throw new ValidateException("生成支付订单失败,订单金额不正确");
}
orderInfo.setPackFee(packAmount.getPrice());
@ -466,6 +553,218 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
return CzgResult.success();
}
/**
* 优惠券通用校验规则 不包括门槛校验
*
* @param isVipPrice 是否使用会员价
*/
private ShopCoupon checkCoupon(MkShopCouponRecord record, boolean isVipPrice) {
ShopCoupon coupon = couponService.getById(record.getCouponId());
AssertUtil.isNull(coupon, "生成支付订单失败,券信息不存在");
if (isVipPrice && coupon.getVipPriceShare() != 1) {
throw new ValidateException("生成支付订单失败,券:" + coupon.getTitle() + "与会员价不共享");
}
isUseLimit(coupon, record);
isUseTime(coupon);
return coupon;
}
/**
* 判断每日使用限量
*/
private void isUseLimit(ShopCoupon coupon, MkShopCouponRecord record) {
if (coupon.getUseLimit() != -10086) {
long useNum = couponRecordService.count(new QueryWrapper()
.eq(MkShopCouponRecord::getCouponId, coupon.getId())
.eq(MkShopCouponRecord::getShopId, record.getShopId())
.eq(MkShopCouponRecord::getUserId, record.getUserId())
.eq(MkShopCouponRecord::getStatus, 1)
.between(MkShopCouponRecord::getUseTime, LocalDateTime.now().with(LocalTime.MIN), LocalDateTime.now().with(LocalTime.MAX))
);
if (useNum >= coupon.getUseLimit()) {
throw new ValidateException("优惠券:" + coupon.getTitle() + " 已达到今日使用限量");
}
}
}
/**
* 使用时段校验
*/
private void isUseTime(ShopCoupon coupon) {
if (!coupon.getUseDays().contains(CzgStrUtils.getStrWeek())) {
throw new ValidateException("生成支付订单失败," + coupon.getTitle() + " 今天不可用");
}
if (!"all".equals(coupon.getUseTimeType())) {
// 获取当前时间仅包含时分秒
LocalTime currentTime = LocalTime.now();
LocalTime startTime = coupon.getUseStartTime().toLocalTime();
LocalTime endTime = coupon.getUseEndTime().toLocalTime();
if (currentTime.isBefore(startTime)) {
if (startTime.isBefore(endTime)) {
throw new ValidateException("生成支付订单失败,优惠券:" + coupon.getTitle() + " 当前时段不可用");
} else if (currentTime.isAfter(endTime)) {
throw new ValidateException("生成支付订单失败,优惠券:" + coupon.getTitle() + " 当前时段不可用");
}
} else if (startTime.isBefore(endTime)) {
if (currentTime.isAfter(endTime)) {
throw new ValidateException("生成支付订单失败,优惠券:" + coupon.getTitle() + " 当前时段不可用");
}
}
}
}
/**
* 商品优惠券计算
*/
private void foodsCalculate(List<OrderDetail> orderDetails, boolean isAllFoods, List<Long> couponFoodIds, int discountNum, boolean isAsc, BigDecimalDTO prodCouponAmount) {
orderDetails = getDetailsSort(orderDetails, isAsc);
BigDecimal remaining = new BigDecimal(discountNum);
for (OrderDetail detail : orderDetails) {
if ((isAllFoods || couponFoodIds.contains(detail.getProductId())) && detail.getUnitPrice().compareTo(BigDecimal.ZERO) > 0) {
if (remaining.compareTo(BigDecimal.ZERO) > 0) {
if (remaining.compareTo(detail.getNum().subtract(detail.getReturnNum())) >= 0) {
detail.setCouponNum(detail.getNum().subtract(detail.getReturnNum()).setScale(2, RoundingMode.CEILING));
detail.setDiscountAmount(detail.getPayAmount());
detail.setPayAmount(BigDecimal.ZERO);
remaining = remaining.subtract(detail.getNum().subtract(detail.getReturnNum()).setScale(2, RoundingMode.CEILING));
} else {
detail.setCouponNum(remaining);
detail.setDiscountAmount(remaining.multiply(detail.getUnitPrice()).setScale(2, RoundingMode.DOWN));
detail.setPayAmount(detail.getPayAmount().subtract(detail.getDiscountAmount()));
remaining = BigDecimal.ZERO;
}
prodCouponAmount.setPrice(prodCouponAmount.getPrice().add(detail.getDiscountAmount()));
}
}
if (remaining.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
}
}
/**
* 买一送一优惠券计算
*/
private void oneGiftCalculate(List<OrderDetail> orderDetails, boolean isAllFoods, List<Long> couponFoodIds, boolean isAsc, BigDecimalDTO oneGiftAmount) {
orderDetails = getDetailsSort(orderDetails, isAsc);
for (OrderDetail detail : orderDetails) {
if ((isAllFoods || couponFoodIds.contains(detail.getProductId())) && couponFoodIds.contains(detail.getProductId())
&& detail.getUnitPrice().compareTo(BigDecimal.ZERO) > 0
&& detail.getNum().subtract(detail.getReturnNum()).subtract(detail.getCouponNum()).compareTo(BigDecimal.TWO) >= 0) {
detail.setCouponNum(detail.getCouponNum().add(BigDecimal.ONE));
detail.setDiscountAmount(detail.getDiscountAmount().add(detail.getUnitPrice()));
detail.setPayAmount(detail.getPayAmount().subtract(detail.getUnitPrice()));
oneGiftAmount.setPrice(detail.getUnitPrice());
return;
}
}
}
/**
* 第二件半价优惠券计算
*/
private void twoHalfCalculate(List<OrderDetail> orderDetails, boolean isAllFoods, List<Long> couponFoodIds, boolean isAsc, BigDecimalDTO oneGiftAmount) {
orderDetails = getDetailsSort(orderDetails, isAsc);
for (OrderDetail detail : orderDetails) {
if ((isAllFoods || couponFoodIds.contains(detail.getProductId())) && couponFoodIds.contains(detail.getProductId())
&& detail.getUnitPrice().compareTo(BigDecimal.ZERO) > 0
&& detail.getNum().subtract(detail.getReturnNum()).subtract(detail.getCouponNum()).compareTo(BigDecimal.TWO) >= 0) {
detail.setHalfPriceCouponNum(BigDecimal.ONE);
BigDecimal halfPrice = detail.getUnitPrice().divide(new BigDecimal("2").setScale(2, RoundingMode.FLOOR));
detail.setDiscountAmount(detail.getDiscountAmount().add(halfPrice));
detail.setPayAmount(detail.getPayAmount().subtract(halfPrice));
oneGiftAmount.setPrice(halfPrice);
return;
}
}
}
/**
* 满减券/折扣券 门槛计算
*
* @param couponFoodIds 门槛商品
*/
private void thresholdCalculate(List<OrderDetail> orderDetails, boolean isAllFoods, List<Long> couponFoodIds, BigDecimal thresholdAmount) {
BigDecimal foodsAmount = BigDecimal.ZERO;
for (OrderDetail detail : orderDetails) {
if ((isAllFoods || couponFoodIds.contains(detail.getProductId())) || couponFoodIds.contains(detail.getProductId())
&& detail.getUnitPrice().compareTo(BigDecimal.ZERO) > 0
&& detail.getNum().subtract(detail.getReturnNum()).subtract(detail.getCouponNum()).compareTo(BigDecimal.ONE) >= 0) {
foodsAmount = foodsAmount.add(detail.getPayAmount());
if (foodsAmount.compareTo(thresholdAmount) >= 0) {
return;
}
}
}
if (foodsAmount.compareTo(thresholdAmount) < 0) {
throw new ValidateException("优惠券未达到门槛金额");
}
}
/**
* 获取价格排序后的orderDetail
*
* @param isAsc true为升序
*/
private List<OrderDetail> getDetailsSort(List<OrderDetail> orderDetails, boolean isAsc) {
if (isAsc) {
return orderDetails.stream()
.sorted(Comparator.comparing(OrderDetail::getPrice))
.toList();
} else {
return orderDetails.stream()
.sorted(Comparator.comparing(OrderDetail::getPrice).reversed())
.toList();
}
}
@Override
public void getOrderAmount(List<OrderDetail> orderDetails, BigDecimalDTO totalAmount, BigDecimalDTO packAmount,
BigDecimalDTO tempAmount, boolean isAllPack, Integer userAllPack, boolean isVipPrice) {
for (OrderDetail orderDetail : orderDetails) {
if (orderDetail.getDiscountSaleAmount() != null && orderDetail.getDiscountSaleAmount().compareTo(BigDecimal.ZERO) > 0) {
orderDetail.setUnitPrice(orderDetail.getDiscountSaleAmount());
} else {
if (isVipPrice) {
orderDetail.setUnitPrice(
(orderDetail.getMemberPrice() == null || orderDetail.getMemberPrice().compareTo(BigDecimal.ZERO) <= 0)
? orderDetail.getPrice() : orderDetail.getMemberPrice());
} else {
orderDetail.setUnitPrice(orderDetail.getPrice());
}
}
if (userAllPack != null) {
if (userAllPack.equals(1)) {
orderDetail.setPackNumber(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
if ("weight".equals(orderDetail.getProductType())) {
orderDetail.setPackNumber(BigDecimal.ONE);
}
} else {
orderDetail.setPackNumber(BigDecimal.ZERO);
}
} else if (isAllPack) {
if ("weight".equals(orderDetail.getProductType())) {
orderDetail.setPackNumber(BigDecimal.ONE);
} else {
orderDetail.setPackNumber(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
}
} else {
if ("weight".equals(orderDetail.getProductType()) && orderDetail.getPackNumber() != null && orderDetail.getPackNumber().compareTo(BigDecimal.ZERO) > 0) {
orderDetail.setPackNumber(BigDecimal.ONE);
}
}
orderDetail.setCouponNum(BigDecimal.ZERO);
orderDetail.setPayAmount((orderDetail.getNum().subtract(orderDetail.getReturnNum())).multiply(orderDetail.getUnitPrice()).setScale(2, RoundingMode.DOWN));
if (orderDetail.getIsTemporary() == 1) {
tempAmount.setPrice(tempAmount.getPrice().add(orderDetail.getPayAmount()));
}
packAmount.setPrice(packAmount.getPrice().add(orderDetail.getPackAmount().multiply(orderDetail.getPackNumber()).setScale(2, RoundingMode.DOWN)));
totalAmount.setPrice(totalAmount.getPrice().add(orderDetail.getPayAmount()));
}
}
/**
* 填充 单价/付款金额
*
@ -497,127 +796,6 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
}
}
/**
* 填充 优惠券使用数量 以及 付款金额
*
* @param orderDetails 订单详情 需要回填 优惠券抵扣数量
* @param prodCouponMap 使用优惠券<商品id,数量>
* @param prodCouponAmount 商品券优惠金额 商品单价*优惠数量 的总和
* @param totalAmount 最终总金额没加打包费 餐位费 去除优惠券金额后的
*/
@Override
public void processOrderDetails2(List<OrderDetail> orderDetails, Map<Long, Integer> prodCouponMap,
BigDecimalDTO prodCouponAmount, BigDecimalDTO totalAmount, BigDecimalDTO packAmount,
boolean isAllPack, Integer userAllPack, boolean isVipPrice) {
Map<Long, List<OrderDetail>> detailMap = new HashMap<>();
for (OrderDetail detail : orderDetails) {
detailMap.computeIfAbsent(detail.getProductId(), k -> new ArrayList<>()).add(detail);
}
List<OrderDetail> resultList = new ArrayList<>();
for (Map.Entry<Long, List<OrderDetail>> entry : detailMap.entrySet()) {
Long key = entry.getKey();
List<OrderDetail> value = entry.getValue();
BigDecimal couponNum = BigDecimal.ZERO;
if (CollUtil.isNotEmpty(prodCouponMap) && prodCouponMap.containsKey(key)) {
couponNum = new BigDecimal(prodCouponMap.get(key));
if (value.size() > 1) {
value.sort(Comparator.comparing(OrderDetail::getPrice));
}
}
for (OrderDetail orderDetail : value) {
if (orderDetail.getDiscountSaleAmount() != null && orderDetail.getDiscountSaleAmount().compareTo(BigDecimal.ZERO) > 0) {
orderDetail.setUnitPrice(orderDetail.getDiscountSaleAmount());
} else {
if (isVipPrice) {
orderDetail.setUnitPrice(
(orderDetail.getMemberPrice() == null || orderDetail.getMemberPrice().compareTo(BigDecimal.ZERO) <= 0)
? orderDetail.getPrice() : orderDetail.getMemberPrice());
} else {
orderDetail.setUnitPrice(orderDetail.getPrice());
}
}
if (userAllPack != null) {
if (userAllPack.equals(1)) {
orderDetail.setPackNumber(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
if ("weight".equals(orderDetail.getProductType())) {
orderDetail.setPackNumber(BigDecimal.ONE);
}
} else {
orderDetail.setPackNumber(BigDecimal.ZERO);
}
} else if (isAllPack) {
if ("weight".equals(orderDetail.getProductType())) {
orderDetail.setPackNumber(BigDecimal.ONE);
} else {
orderDetail.setPackNumber(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
}
} else {
if ("weight".equals(orderDetail.getProductType()) && orderDetail.getPackNumber() != null && orderDetail.getPackNumber().compareTo(BigDecimal.ZERO) > 0) {
orderDetail.setPackNumber(BigDecimal.ONE);
}
}
packAmount.setPrice(packAmount.getPrice().add(orderDetail.getPackAmount().multiply(orderDetail.getPackNumber()).setScale(2, RoundingMode.DOWN)));
if (couponNum.compareTo(BigDecimal.ZERO) > 0) {
if (couponNum.compareTo(orderDetail.getNum()) >= 0) {
orderDetail.setCouponNum(orderDetail.getNum());
orderDetail.setPayAmount(BigDecimal.ZERO);
couponNum = couponNum.subtract(orderDetail.getNum());
} else {
orderDetail.setCouponNum(couponNum);
orderDetail.setPayAmount((orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(couponNum)).multiply(orderDetail.getUnitPrice()).setScale(2, RoundingMode.DOWN));
couponNum = BigDecimal.ZERO;
}
prodCouponAmount.setPrice((prodCouponAmount.getPrice().add(orderDetail.getUnitPrice())).multiply(orderDetail.getCouponNum()).setScale(2, RoundingMode.DOWN));
} else {
orderDetail.setCouponNum(BigDecimal.ZERO);
orderDetail.setPayAmount((orderDetail.getNum().subtract(orderDetail.getReturnNum())).multiply(orderDetail.getUnitPrice()).setScale(2, RoundingMode.DOWN));
}
totalAmount.setPrice(totalAmount.getPrice().add(orderDetail.getPayAmount()));
resultList.add(orderDetail);
}
// if (couponNum.compareTo(BigDecimal.ZERO) != 0) {
// throw new ValidateException("生成支付订单失败,优惠券数量不正确");
// }
}
orderDetails = resultList;
}
/**
* 校验优惠券可用性
*/
private void checkCoupon(Map<Long, Integer> prodCouponMap, BigDecimalDTO fullAmount, BigDecimalDTO discountAmount, CheckOrderPay param) {
if (CollUtil.isNotEmpty(param.getCouponList())) {
//TODO 校验优惠券
// //校验优惠券
// List<ShopActivateCouponRecord> records = couponRecordService.listAs(
// QueryWrapper.create()
// .where(ShopActivateCouponRecord::getId).in(param.getCouponList())
// .and(ShopActivateCouponRecord::getStatus).eq(0), ShopActivateCouponRecord.class);
// if (CollUtil.isEmpty(records)) {
// throw new ValidateException("生成支付订单失败,优惠券信息不存在");
// } else if (records.size() != param.getCouponList().size()) {
// throw new ValidateException("生成支付订单失败,优惠券信息不正确");
// }
// boolean isFullMinus = false;
// for (ShopActivateCouponRecord record : records) {
// if (record.getType().equals(1)) {
// if (isFullMinus) {
// throw new ValidateException("生成支付订单失败,满减券仅可使用一张");
// }
// fullAmount.setPrice(record.getFullAmount());
// discountAmount.setPrice(record.getDiscountAmount());
// isFullMinus = true;
// } else if (record.getType().equals(2)) {
// prodCouponMap.compute(record.getProId(), (key, oldValue) -> oldValue == null ? 1 : oldValue + 1);
// }
// }
if (discountAmount.getPrice().compareTo(param.getFullCouponDiscountAmount()) != 0) {
throw new ValidateException("生成支付订单失败,满减券减免金额不正确");
}
}
}
@Override
@Transactional
public void payCallBackOrder(@NotBlank String orderNo, @NotNull JSONObject resultJson, int retryCount) {
@ -695,7 +873,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
}
}
}else if ("memberPay".equals(payment.getPayType())) {
} else if ("memberPay".equals(payment.getPayType())) {
memberConfigService.joinMember(payment.getShopId(), payment.getSourceId(), payment.getRelatedId());
}
}
@ -784,7 +962,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
//券消耗
List<Long> coupons = JSON.parseArray(orderInfo.getCouponInfoList(), Long.class);
if (CollUtil.isNotEmpty(coupons)) {
// couponService.use(coupons, shopUser.getId(), orderInfo.getId());
couponService.use(coupons, shopUser.getId(), orderInfo.getId());
}
}
String[] payTypes = {PayEnums.VIP_PAY.getValue(), PayEnums.CREDIT_PAY.getValue()};
@ -937,7 +1115,8 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
orderInfo.setOrderAmount(param.getOrderAmount());
orderInfo.setPointsDiscountAmount(param.getPointsDiscountAmount());
orderInfo.setProductCouponDiscountAmount(param.getProductCouponDiscountAmount());
orderInfo.setFullCouponDiscountAmount(param.getFullCouponDiscountAmount());
// orderInfo.setFullCouponDiscountAmount(param.getFullCouponDiscountAmount());
orderInfo.setOtherCouponDiscountAmount(param.getOtherCouponDiscountAmount());
orderInfo.setDiscountAmount(param.getDiscountAmount());
//优惠券
orderInfo.setCouponInfoList(CollUtil.isEmpty(param.getCouponList()) ? "" : JSONObject.toJSONString(param.getCouponList()));
@ -971,7 +1150,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
//券消耗
List<Long> coupons = JSON.parseArray(orderInfo.getCouponInfoList(), Long.class);
if (CollUtil.isNotEmpty(coupons)) {
// couponService.use(coupons, shopUser.getId(), orderInfo.getId());
couponService.use(coupons, shopUser.getId(), orderInfo.getId());
}
}
}
@ -994,6 +1173,9 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
if (orderInfo.getFullCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
jsonObject.put("满减券抵扣", orderInfo.getFullCouponDiscountAmount());
}
if(orderInfo.getOtherCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0){
jsonObject.put("其它优惠券折扣", orderInfo.getOtherCouponDiscountAmount());
}
if (orderInfo.getPointsDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
jsonObject.put("积分抵扣", orderInfo.getPointsDiscountAmount());
}

View File

@ -75,11 +75,11 @@ public class PayServiceImpl implements PayService {
private UserInfoService userInfoService;
@DubboReference
private ShopInfoService shopInfoService;
// @DubboReference
// @DubboReference
// private ShopActivateService shopActivateService;
@DubboReference
private ShopUserFlowService userFlowService;
// @DubboReference
// @DubboReference
// private ShopCouponService couponService;
@DubboReference
private MemberPointsService pointsService;
@ -147,7 +147,8 @@ public class PayServiceImpl implements PayService {
BigDecimalDTO totalAmount = new BigDecimalDTO(BigDecimal.ZERO);
//最终打包费
BigDecimalDTO packAmount = new BigDecimalDTO(BigDecimal.ZERO);
orderInfoService.processOrderDetails2(orderDetails, null, null, totalAmount, packAmount, payParam.isAllPack(), payParam.getUserAllPack(), false);
BigDecimalDTO tempAmount = new BigDecimalDTO(BigDecimal.ZERO);
orderInfoService.getOrderAmount(orderDetails, totalAmount, packAmount, tempAmount, payParam.isAllPack(), payParam.getUserAllPack(), false);
BigDecimal total = totalAmount.getPrice().add(packAmount.getPrice());
if (total.compareTo(freeConfig.getRechargeThreshold()) < 0) {
throw new CzgException("霸王餐满" + freeConfig.getRechargeThreshold() + "可用,当前订单金额为" + total);