Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17

This commit is contained in:
YunaiV
2024-12-27 21:29:41 +08:00
20 changed files with 115 additions and 32 deletions

View File

@@ -48,4 +48,9 @@ public class AppProductSpuRespVO {
@Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer salesCount;
// ========== 物流相关字段 =========
@Schema(description = "配送方式数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private List<Integer> deliveryTypes;
}

View File

@@ -78,7 +78,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
@Transactional(rollbackFor = Exception.class)
public void updateSpu(ProductSpuSaveReqVO updateReqVO) {
// 校验 SPU 是否存在
validateSpuExists(updateReqVO.getId());
ProductSpuDO spu = validateSpuExists(updateReqVO.getId());
// 校验分类、品牌
validateCategory(updateReqVO.getCategoryId());
brandService.validateProductBrand(updateReqVO.getBrandId());
@@ -87,7 +87,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
// 更新 SPU
ProductSpuDO updateObj = BeanUtils.toBean(updateReqVO, ProductSpuDO.class);
ProductSpuDO updateObj = BeanUtils.toBean(updateReqVO, ProductSpuDO.class).setStatus(spu.getStatus());
initSpuFromSkus(updateObj, skuSaveReqList);
productSpuMapper.updateById(updateObj);
// 批量更新 SKU
@@ -176,10 +176,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
productSkuService.deleteSkuBySpuId(id);
}
private void validateSpuExists(Long id) {
if (productSpuMapper.selectById(id) == null) {
private ProductSpuDO validateSpuExists(Long id) {
ProductSpuDO spuDO = productSpuMapper.selectById(id);
if (spuDO == null) {
throw exception(SPU_NOT_EXISTS);
}
return spuDO;
}
@Override

View File

@@ -152,7 +152,7 @@ public class CouponServiceImpl implements CouponService {
findAndThen(userCouponIdsMap, userId, couponIds::addAll);
}
} catch (Exception e) {
log.error("[takeCouponsByAdmin][coupon({}) 优惠券发放失败]", entry, e);
log.error("[takeCouponsByAdmin][coupon({}) 优惠券发放失败 userId({})]", entry, userId, e);
}
}
return couponIds;

View File

@@ -93,6 +93,7 @@ public interface ErrorCodeConstants {
ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1_011_007_006, "已绑定了推广人");
ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级");
ErrorCode BROKERAGE_USER_LEVEL_NOT_SUPPORT = new ErrorCode(1_011_007_008, "目前只支持 level 小于等于 2");
ErrorCode BROKERAGE_CREATE_USER_EXISTS = new ErrorCode(1_011_007_009, "分销用户已存在");
// ========== 分销提现 模块 1-011-008-000 ==========
ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1_011_008_000, "佣金提现记录不存在");

View File

@@ -47,6 +47,13 @@ public class BrokerageUserController {
@Resource
private MemberUserApi memberUserApi;
@PostMapping("/create")
@Operation(summary = "创建分销用户")
@PreAuthorize("@ss.hasPermission('trade:brokerage-user:create')")
public CommonResult<Long> createBrokerageUser(@Valid @RequestBody BrokerageUserCreateReqVO createReqVO) {
return success(brokerageUserService.createBrokerageUser(createReqVO));
}
@PutMapping("/update-bind-user")
@Operation(summary = "修改推广员")
@PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-bind-user')")

View File

@@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 分销用户创建 Request VO")
@Data
public class BrokerageUserCreateReqVO {
@Schema(description = "分销用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "分销用户编号不能为空")
private Long userId;
@Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587")
private Long bindUserId;
}

View File

@@ -59,6 +59,9 @@ public interface BrokerageUserConvert {
}
default BrokerageUserRespVO copyTo(MemberUserRespDTO source, BrokerageUserRespVO target) {
if (target == null) {
return null;
}
Optional.ofNullable(source).ifPresent(
user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
return target;

View File

@@ -27,7 +27,7 @@ import java.util.Map;
*
* @author 芋道源码
*/
@TableName("trade_order")
@TableName(value = "trade_order", autoResultMap = true)
@KeySequence("trade_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -26,12 +26,12 @@ import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO;
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
@@ -79,7 +79,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
TradeConfigDO memberConfig = tradeConfigService.getTradeConfig();
// 0 未启用分销功能
if (memberConfig == null || !BooleanUtil.isTrue(memberConfig.getBrokerageEnabled())) {
log.warn("[addBrokerage][增加佣金失败brokerageEnabled 未配置userId({})", userId);
log.error("[addBrokerage][增加佣金失败brokerageEnabled 未配置userId({}) bizType({}) list({})", userId, bizType, list);
return;
}

View File

@@ -1,12 +1,14 @@
package cn.iocoder.yudao.module.trade.service.brokerage;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByUserCountRespVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
/**
@@ -107,6 +109,14 @@ public interface BrokerageUserService {
*/
boolean bindBrokerageUser(@NotNull Long userId, @NotNull Long bindUserId);
/**
* 【管理员】创建分销用户
*
* @param createReqVO 请求
* @return 编号
*/
Long createBrokerageUser(@Valid BrokerageUserCreateReqVO createReqVO);
/**
* 获取用户是否有分销资格
*

View File

@@ -8,9 +8,11 @@ import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
@@ -28,6 +30,7 @@ import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
@@ -110,7 +113,6 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
if (brokerageUserDO == null) {
throw exception(BROKERAGE_USER_NOT_EXISTS);
}
return brokerageUserDO;
}
@@ -202,6 +204,24 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Long createBrokerageUser(BrokerageUserCreateReqVO createReqVO) {
// 1.1 校验分销用户是否已存在
BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(createReqVO.getUserId());
if (brokerageUser != null) {
throw exception(BROKERAGE_CREATE_USER_EXISTS);
}
// 1.2 校验是否能绑定用户
brokerageUser = BeanUtils.toBean(createReqVO, BrokerageUserDO.class).setId(createReqVO.getUserId())
.setBrokerageTime(LocalDateTime.now());
validateCanBindUser(brokerageUser, createReqVO.getBindUserId());
// 2. 创建分销人
brokerageUserMapper.insert(brokerageUser);
return brokerageUser.getId();
}
/**
* 补全绑定用户的字段
*

View File

@@ -329,7 +329,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
/**
* 校验支付订单的合法性
*
* @param order 交易订单
* @param order 交易订单
* @param payOrderId 支付订单编号
* @return 支付订单
*/
@@ -748,7 +748,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
}
DeliveryPickUpStoreDO deliveryPickUpStore = pickUpStoreService.getDeliveryPickUpStore(order.getPickUpStoreId());
if (deliveryPickUpStore == null
|| !CollUtil.contains(deliveryPickUpStore.getVerifyUserIds(), userId)) {
|| !CollUtil.contains(deliveryPickUpStore.getVerifyUserIds(), userId)) {
throw exception(ORDER_PICK_UP_FAIL_NOT_VERIFY_USER);
}

View File

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@@ -19,6 +20,7 @@ import java.util.List;
* @author 芋道源码
*/
@Component
@Slf4j
public class TradeCouponOrderHandler implements TradeOrderHandler {
@Resource
@@ -46,11 +48,15 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
return;
}
// 赠送优惠券
List<Long> couponIds = couponApi.takeCouponsByAdmin(order.getGiveCouponTemplateCounts(), order.getUserId());
if (CollUtil.isEmpty(couponIds)) {
return;
try {
List<Long> couponIds = couponApi.takeCouponsByAdmin(order.getGiveCouponTemplateCounts(), order.getUserId());
if (CollUtil.isEmpty(couponIds)) {
return;
}
orderUpdateService.updateOrderGiveCouponIds(order.getUserId(), order.getId(), couponIds);
} catch (Exception e) {
log.error("[afterPayOrder][order({}) 赠送优惠券({})失败,需要手工补偿]", order.getId(), order.getGiveCouponTemplateCounts(), e);
}
orderUpdateService.updateOrderGiveCouponIds(order.getUserId(), order.getId(), couponIds);
}
@Override

View File

@@ -122,9 +122,13 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
*/
private boolean isGlobalExpressFree(TradePriceCalculateRespBO result) {
TradeConfigDO config = tradeConfigService.getTradeConfig();
return config == null
|| Boolean.TRUE.equals(config.getDeliveryExpressFreeEnabled()) // 开启包邮
|| result.getPrice().getPayPrice() >= config.getDeliveryExpressFreePrice(); // 满足包邮的价格
// 情况一:交易中心配置不存在默认不包邮
if (config == null) {
return false;
}
// 情况二:开启了全局包邮 && 满足包邮金额
return Boolean.TRUE.equals(config.getDeliveryExpressFreeEnabled()) &&
result.getPrice().getPayPrice() >= config.getDeliveryExpressFreePrice();
}
private void calculateDeliveryPrice(List<OrderItem> selectedSkus,