diff --git a/DB/version4.3toMASTER.sql b/DB/version4.3to4.4.sql similarity index 95% rename from DB/version4.3toMASTER.sql rename to DB/version4.3to4.4.sql index eba294c6..18f00388 100644 --- a/DB/version4.3toMASTER.sql +++ b/DB/version4.3to4.4.sql @@ -68,8 +68,6 @@ CREATE TABLE `li_order_package_item` ( */ ALTER TABLE li_order_item ADD `deliver_number` int DEFAULT NULL COMMENT '发货数量'; -ALTER TABLE li_goods_sku ADD `alert_quantity` int DEFAULT NULL COMMENT '预警库存'; - /* sku增加预警库存 */ @@ -105,7 +103,7 @@ WHERE sf.flow_type = 'REFUND' AND sf.store_id=b.store_id AND sf.create_time BETWEEN b.start_time - AND b.end_time),0) + AND b.end_time),0); UPDATE li_bill b SET b.kanjia_refund_settlement_price =IFNULL(( @@ -119,20 +117,6 @@ SET b.kanjia_refund_settlement_price =IFNULL(( AND sf.create_time BETWEEN b.start_time AND b.end_time),0); - - -/** - 交易唤醒表,增加交易流水详情 - */ -ALTER TABLE li_order_item ADD `is_refund` varchar(255) DEFAULT NULL COMMENT '是否退款'; - -/** - 交易表增加订单状态字段 - */ -ALTER TABLE li_order_item ADD `refund_price` decimal(10,2) DEFAULT NULL COMMENT '退款金额'; - - - /** 文件表增加拥有者名称 */ diff --git a/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java b/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java index dbea9b24..61b555e8 100644 --- a/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java +++ b/framework/src/main/java/cn/lili/modules/goods/service/GoodsSkuService.java @@ -296,4 +296,13 @@ public interface GoodsSkuService extends IService { * @return 库存数量 */ Integer getGoodsStock(String goodsId); + + /** + * 更新sku运费模版 + * + * @param goodsId 商品id + * @param templateId 运费模版id + * @return 操作结果 + */ + Boolean freight(List goodsId, String templateId); } \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java index b3c9e18e..6909add2 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsServiceImpl.java @@ -437,6 +437,7 @@ public class GoodsServiceImpl extends ServiceImpl implements lambdaUpdateWrapper.in(Goods::getId, goodsIds); List goodsCache = goodsIds.stream().map(item -> CachePrefix.GOODS.getPrefix() + item).collect(Collectors.toList()); cache.multiDel(goodsCache); + goodsSkuService.freight(goodsIds, templateId); return this.update(lambdaUpdateWrapper); } diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java index d67639ff..b71b1eae 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/GoodsSkuServiceImpl.java @@ -888,6 +888,17 @@ public class GoodsSkuServiceImpl extends ServiceImpl i } + @Override + public Boolean freight(List goodsId, String templateId) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(GoodsSku::getGoodsId, goodsId); + updateWrapper.set(GoodsSku::getFreightTemplateId, templateId); + updateWrapper.set(GoodsSku::getUpdateTime, new Date()); + List skuIds = this.list(updateWrapper).stream().map(GoodsSku::getId).collect(Collectors.toList()); + skuIds.forEach(this::clearCache); + return this.update(updateWrapper); + } + /** * 渲染商品sku * diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java index 04081748..469bfba7 100644 --- a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java @@ -233,7 +233,7 @@ public class MemberServiceImpl extends ServiceImpl impleme private Member findMember(String userName) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("username", userName).or().eq("mobile", userName); - return this.getOne(queryWrapper); + return this.getOne(queryWrapper, false); } @Override diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java b/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java index d375c16f..f3dedc37 100644 --- a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java +++ b/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java @@ -1,5 +1,6 @@ package cn.lili.modules.order.cart.render.util; +import cn.hutool.core.map.MapUtil; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.utils.CurrencyUtil; import cn.lili.modules.order.cart.entity.dto.TradeDTO; @@ -10,7 +11,8 @@ import lombok.extern.slf4j.Slf4j; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * 促销价格计算业务层实现 @@ -33,7 +35,7 @@ public class PromotionPriceUtil { PromotionTypeEnum promotionTypeEnum, String activityId) { // sku 促销信息非空判定 - if (skuPromotionDetail == null || skuPromotionDetail.size() == 0) { + if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) { return; } @@ -68,40 +70,39 @@ public class PromotionPriceUtil { List skuVOList = tradeDTO.getSkuList(); // 获取map分配sku的总数,如果是最后一个商品分配金额,则将金额从百分比改为总金额扣减,避免出现小数除不尽 - int count = skuPromotionDetail.size(); + AtomicInteger count = new AtomicInteger(skuPromotionDetail.size()); //已优惠金额 - Double deducted = 0D; + AtomicReference deducted = new AtomicReference<>(0D); for (String skuId : skuPromotionDetail.keySet()) { //获取对应商品进行计算 - for (CartSkuVO cartSkuVO : skuVOList) { - if (cartSkuVO.getGoodsSku().getId().equals(skuId)) { + Double finalDiscountPrice = discountPrice; + Double finalTotalPrice = totalPrice; + skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> { + //sku 优惠金额 + Double skuDiscountPrice; + count.getAndDecrement(); - count--; - - //sku 优惠金额 - Double skuDiscountPrice; - - //非最后一个商品,则按照比例计算 - if (count > 0) { - //商品金额占比 - double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4); - //商品优惠金额 - skuDiscountPrice = CurrencyUtil.mul(discountPrice, point); - //累加已优惠金额 - deducted = CurrencyUtil.add(deducted, skuDiscountPrice); - } - // 如果是最后一个商品 则减去之前优惠的金额来进行计算 - else { - skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted); - } - - calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId); + //非最后一个商品,则按照比例计算 + if (count.get() > 0) { + //商品金额占比 + double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), finalTotalPrice, 4); + //商品优惠金额 + skuDiscountPrice = CurrencyUtil.mul(finalDiscountPrice, point); + //累加已优惠金额 + deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice)); } - } + // 如果是最后一个商品 则减去之前优惠的金额来进行计算 + else { + skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get()); + } + + calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId); + }); + } calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId); @@ -186,51 +187,100 @@ public class PromotionPriceUtil { // 特殊情况处理,如参与多个促销活动,部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额 // 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额,则分摊到其他商品上 // 满足当前促销的总优惠金额 - if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) { + if (skuPromotionDetail == null || skuPromotionDetail.size() < 2) { return; } + + // clone skuPromotionDetail + Map skuPromotionDetailClone = MapUtil.sortByValue(skuPromotionDetail, false); + + // 未满足优惠金额的商品 long matchPromotionsZeroCount = - skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count(); - long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count(); + skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetailClone.containsKey(l.getGoodsSku().getId())).count(); + // 参与当前促销活动的商品 + long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetailClone.containsKey(l.getGoodsSku().getId())).count(); if (matchPromotionsZeroCount == matchPromotionsCount) { return; } - // 获取剩余金额不足优惠金额的商品 - List unEnoughSku = skuVOList.stream().filter(k -> { - if (skuPromotionDetail.containsKey(k.getGoodsSku().getId()) && skuPromotionDetail.size() >= 2) { - //商品金额占比 - double point = CurrencyUtil.div(k.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4); - //商品优惠金额 - Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point); - return k.getPriceDetailDTO().getCouponPrice() > 0 && skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice(); + // 分配到其他商品的优惠金额 + AtomicReference balance = new AtomicReference<>(0D); + StringBuilder lastSkuId = new StringBuilder(); + + // 计数器 + int count = 0; + + + // 检查是否有不满足优惠金额的商品 + filterEnoughSku(skuVOList, skuPromotionDetailClone, discountPrice, totalPrice, balance, lastSkuId, promotionTypeEnum, activityId); + + // 循环 优惠金额分摊,直到所有商品都满足优惠金额 + while (true) { + // 如果还有剩余金额,则继续分摊 + if (balance.get() > 0) { + skuPromotionDetailClone.remove(lastSkuId.toString()); + double lastDiscountPrice = CurrencyUtil.sub(discountPrice, skuPromotionDetail.get(lastSkuId.toString())); + double lastTotalPrice = CurrencyUtil.sub(totalPrice, skuPromotionDetail.get(lastSkuId.toString())); + filterEnoughSku(skuVOList, skuPromotionDetailClone, lastDiscountPrice, lastTotalPrice, balance, lastSkuId, promotionTypeEnum, activityId); + } else { + break; } - return false; - }).collect(Collectors.toList()); - if (!unEnoughSku.isEmpty()) { - if (unEnoughSku.size() == skuVOList.size()) { - return; + count++; + + // 防止死循环 + if (count > skuPromotionDetail.size()) { + break; } - for (CartSkuVO cartSkuVO : skuVOList) { - if (unEnoughSku.isEmpty()) { - break; - } - if (skuPromotionDetail.containsKey(cartSkuVO.getGoodsSku().getId()) && unEnoughSku.stream().noneMatch(k -> k.getGoodsSku().getId().equals(cartSkuVO.getGoodsSku().getId()))) { - // 商品金额占比 - double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4); - // 商品优惠金额 - Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point); - // 商品优惠金额 - 不足优惠金额 = 差额 - Double sub = CurrencyUtil.sub(skuDiscountPrice, unEnoughSku.get(0).getPriceDetailDTO().getCouponPrice()); - // 分摊到其他商品: 其他商品原优惠金额 + 差额 - calculateCartSkuPromotionsPrice(cartSkuVO, sub, promotionTypeEnum, activityId); - // 从不足商品列表中移除 - unEnoughSku.remove(0); - } - } - } else { - return; } - calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId); + } + + + private static void filterEnoughSku(List skuVOList, Map skuPromotionDetail, + Double discountPrice, Double totalPrice, + AtomicReference balance, StringBuilder lastSkuId, + PromotionTypeEnum promotionTypeEnum, String activityId) { + AtomicInteger count = new AtomicInteger(skuPromotionDetail.size()); + AtomicReference countPrice = new AtomicReference<>(0D); + for (String skuId : skuPromotionDetail.keySet()) { + skuVOList.forEach(l -> { + if (l.getGoodsSku().getId().equals(skuId)) { + count.getAndDecrement(); + + //商品金额占比 + double point = CurrencyUtil.div(l.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4); + + //商品优惠金额 + Double skuDiscountPrice; + + if (count.get() > 0) { + //非最后一个商品,则按照比例计算 + skuDiscountPrice = CurrencyUtil.mul(discountPrice, point); + } else { + // 如果是最后一个商品 则减去之前优惠的金额来进行计算 + skuDiscountPrice = CurrencyUtil.sub(discountPrice, countPrice.get()); + + + } + + if (balance.get() > 0) { + // 分摊到其他商品: 其他商品原优惠金额 + 差额 + calculateCartSkuPromotionsPrice(l, balance.get(), promotionTypeEnum, activityId); + } + + // 如果商品优惠金额大于商品金额,则取商品金额。差额分摊到其他商品 + if (skuDiscountPrice > l.getPriceDetailDTO().getGoodsPrice()) { + balance.set(CurrencyUtil.sub(skuDiscountPrice, l.getPriceDetailDTO().getGoodsPrice())); + lastSkuId.append(skuId); + skuDiscountPrice = l.getPriceDetailDTO().getGoodsPrice(); + } else { + balance.set(0D); + } + + + countPrice.set(CurrencyUtil.add(countPrice.get(), skuDiscountPrice)); + + } + }); + } } /** diff --git a/framework/src/main/java/cn/lili/modules/order/order/entity/dos/Order.java b/framework/src/main/java/cn/lili/modules/order/order/entity/dos/Order.java index f2fc6e88..0ffe52a0 100644 --- a/framework/src/main/java/cn/lili/modules/order/order/entity/dos/Order.java +++ b/framework/src/main/java/cn/lili/modules/order/order/entity/dos/Order.java @@ -243,7 +243,7 @@ public class Order extends BaseEntity { this.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name()); this.setTradeSn(tradeDTO.getSn()); this.setRemark(cartVO.getRemark()); - this.setFreightPrice(tradeDTO.getPriceDetailDTO().getFreightPrice()); + this.setFreightPrice(cartVO.getPriceDetailDTO().getFreightPrice()); //会员收件信息 if (tradeDTO.getMemberAddress() != null && DeliveryMethodEnum.LOGISTICS.name().equals(cartVO.getDeliveryMethod())) { this.setConsigneeAddressIdPath(tradeDTO.getMemberAddress().getConsigneeAddressIdPath()); diff --git a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java index 4f3dce1a..f752e4c5 100644 --- a/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/search/serviceimpl/EsGoodsSearchServiceImpl.java @@ -88,7 +88,7 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService { cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword()); } NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo); -// searchQueryBuilder.withCollapseField("goodsId"); +// searchQueryBuilder.withCollapseField("goodsId.keyword"); NativeSearchQuery searchQuery = searchQueryBuilder.build(); searchQuery.setTrackTotalHits(true); log.debug("searchGoods DSL:{}", searchQuery.getQuery()); diff --git a/framework/src/main/java/cn/lili/modules/sms/impl/SmsUtilAliImplService.java b/framework/src/main/java/cn/lili/modules/sms/impl/SmsUtilAliImplService.java index 5fb22310..1f994e7e 100644 --- a/framework/src/main/java/cn/lili/modules/sms/impl/SmsUtilAliImplService.java +++ b/framework/src/main/java/cn/lili/modules/sms/impl/SmsUtilAliImplService.java @@ -5,8 +5,6 @@ import cn.lili.cache.Cache; import cn.lili.cache.CachePrefix; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; -import cn.lili.common.properties.SmsTemplateProperties; -import cn.lili.common.properties.SystemSettingProperties; import cn.lili.common.security.context.UserContext; import cn.lili.common.utils.CommonUtil; import cn.lili.modules.member.entity.dos.Member; @@ -48,12 +46,6 @@ public class SmsUtilAliImplService implements SmsUtil { @Autowired private SmsPluginFactory smsPluginFactory; - @Autowired - private SmsTemplateProperties smsTemplateProperties; - - @Autowired - private SystemSettingProperties systemSettingProperties; - @Override public void sendSmsCode(String mobile, VerificationEnums verificationEnums, String uuid) { //获取短信配置 @@ -78,18 +70,18 @@ public class SmsUtilAliImplService implements SmsUtil { switch (verificationEnums) { //登录 case LOGIN: { - templateCode = smsTemplateProperties.getLOGIN(); + templateCode = smsSetting.getLoginTemplateCode(); break; } //注册 case BIND_MOBILE: case REGISTER: { - templateCode = smsTemplateProperties.getREGISTER(); + templateCode = smsSetting.getRegisterTemplateCode(); break; } //找回密码 case FIND_USER: { - templateCode = smsTemplateProperties.getFIND_USER(); + templateCode = smsSetting.getFindPasswordTemplateCode(); break; } //修改密码 @@ -100,7 +92,7 @@ public class SmsUtilAliImplService implements SmsUtil { } //更新为用户最新手机号 mobile = member.getMobile(); - templateCode = smsTemplateProperties.getUPDATE_PASSWORD(); + templateCode = smsSetting.getFindPasswordTemplateCode(); break; } //设置支付密码 @@ -108,7 +100,7 @@ public class SmsUtilAliImplService implements SmsUtil { Member member = memberService.getById(UserContext.getCurrentUser().getId()); //更新为用户最新手机号 mobile = member.getMobile(); - templateCode = smsTemplateProperties.getWALLET_PASSWORD(); + templateCode = smsSetting.getWalletPasswordTemplateCode(); break; } //如果不是有效的验证码手段,则此处不进行短信操作 diff --git a/framework/src/main/java/cn/lili/modules/wechat/serviceimpl/WechatMPServiceImpl.java b/framework/src/main/java/cn/lili/modules/wechat/serviceimpl/WechatMPServiceImpl.java index 73cb6f91..4053e3a3 100644 --- a/framework/src/main/java/cn/lili/modules/wechat/serviceimpl/WechatMPServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/wechat/serviceimpl/WechatMPServiceImpl.java @@ -137,7 +137,7 @@ public class WechatMPServiceImpl implements WechatMPService { map.put("upload_time", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now())); //支付者,支付者信息 - Connect connect = connectService.queryConnect(ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()).unionType(SourceEnum.WECHAT_MP_OPEN_ID.name()).build()); + Connect connect = connectService.queryConnect(ConnectQueryDTO.builder().userId(order.getMemberId()).unionType(SourceEnum.WECHAT_MP_OPEN_ID.name()).build()); if (connect == null) { return; } @@ -263,7 +263,7 @@ public class WechatMPServiceImpl implements WechatMPService { private String out_trade_no; public OrderKey(Order order) { - this.order_number_type = 2; + this.order_number_type = 1; this.out_trade_no = order.getPayOrderNo(); this.transaction_id = order.getReceivableNo(); } diff --git a/framework/src/main/resources/script/limit.lua b/framework/src/main/resources/script/limit.lua index e9d5b41e..6fc7fd7e 100644 --- a/framework/src/main/resources/script/limit.lua +++ b/framework/src/main/resources/script/limit.lua @@ -2,7 +2,7 @@ local c c = redis.call('get',KEYS[1]) -- 调用不超过最大值,则直接返回 if c and tonumber(c) > tonumber(ARGV[1]) then - return c; + return tonumber(c); end -- 执行计算器自加 c = redis.call('incr',KEYS[1])