mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
mall模块-限时折扣功能
This commit is contained in:
parent
82fd800ad2
commit
04061b028c
@ -1,11 +1,17 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -17,8 +23,11 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 限时折扣活动")
|
||||
@RestController
|
||||
@ -29,6 +38,9 @@ public class DiscountActivityController {
|
||||
@Resource
|
||||
private DiscountActivityService discountActivityService;
|
||||
|
||||
@Resource
|
||||
private ProductSpuApi productSpuApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建限时折扣活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')")
|
||||
@ -49,7 +61,7 @@ public class DiscountActivityController {
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')")
|
||||
public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
|
||||
discountActivityService.closeRewardActivity(id);
|
||||
discountActivityService.closeDiscountActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@ -81,7 +93,18 @@ public class DiscountActivityController {
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
|
||||
public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
|
||||
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
|
||||
return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult));
|
||||
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
// 拼接数据
|
||||
List<DiscountProductDO> products = discountActivityService.getDiscountProductsByActivityId(
|
||||
convertSet(pageResult.getList(), DiscountActivityDO::getId));
|
||||
|
||||
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(
|
||||
convertSet(products, DiscountProductDO::getSpuId));
|
||||
|
||||
return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products, spuList));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 限时折扣活动 Response VO")
|
||||
@Data
|
||||
@ -24,4 +25,25 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<DiscountActivityBaseVO.Product> products;
|
||||
|
||||
|
||||
// ========== 商品字段 ==========
|
||||
|
||||
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
|
||||
example = "618大促")
|
||||
private String spuName;
|
||||
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取
|
||||
example = "https://www.iocoder.cn/xx.png")
|
||||
private String picUrl;
|
||||
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取
|
||||
example = "50")
|
||||
private Integer marketPrice;
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,15 +2,22 @@ package cn.iocoder.yudao.module.promotion.convert.discount;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 限时折扣活动 Convert
|
||||
@ -29,14 +36,57 @@ public interface DiscountActivityConvert {
|
||||
DiscountActivityRespVO convert(DiscountActivityDO bean);
|
||||
|
||||
List<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list);
|
||||
List<DiscountActivityBaseVO.Product> convertList2(List<DiscountProductDO> list);
|
||||
|
||||
List<DiscountProductRespDTO> convertList02(List<DiscountProductDO> list);
|
||||
|
||||
PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page);
|
||||
|
||||
default PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page,
|
||||
List<DiscountProductDO> discountProductDOList,
|
||||
List<ProductSpuRespDTO> spuList) {
|
||||
PageResult<DiscountActivityRespVO> pageResult = convertPage(page);
|
||||
|
||||
// 拼接商品
|
||||
Map<Long, DiscountProductDO> discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId);
|
||||
Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId);
|
||||
pageResult.getList().forEach(item -> {
|
||||
item.setProducts(convertList2(discountProductDOList));
|
||||
item.setSpuId(discountActivityMap.get(item.getId())==null?null: discountActivityMap.get(item.getId()).getSpuId());
|
||||
if (item.getSpuId() != null) {
|
||||
MapUtils.findAndThen(spuMap, item.getSpuId(),
|
||||
spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice()));
|
||||
}
|
||||
|
||||
});
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
DiscountProductDO convert(DiscountActivityBaseVO.Product bean);
|
||||
|
||||
DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products);
|
||||
default DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products){
|
||||
if ( activity == null && products == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DiscountActivityDetailRespVO discountActivityDetailRespVO = new DiscountActivityDetailRespVO();
|
||||
|
||||
if ( activity != null ) {
|
||||
discountActivityDetailRespVO.setName( activity.getName() );
|
||||
discountActivityDetailRespVO.setStartTime( activity.getStartTime() );
|
||||
discountActivityDetailRespVO.setEndTime( activity.getEndTime() );
|
||||
discountActivityDetailRespVO.setRemark( activity.getRemark() );
|
||||
discountActivityDetailRespVO.setId( activity.getId() );
|
||||
discountActivityDetailRespVO.setStatus( activity.getStatus() );
|
||||
discountActivityDetailRespVO.setCreateTime( activity.getCreateTime() );
|
||||
}
|
||||
if (!products.isEmpty()) {
|
||||
discountActivityDetailRespVO.setSpuId(products.get(0).getSpuId());
|
||||
}
|
||||
discountActivityDetailRespVO.setProducts( convertList2( products ) );
|
||||
|
||||
return discountActivityDetailRespVO;
|
||||
}
|
||||
|
||||
// =========== 比较是否相等 ==========
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -23,4 +24,10 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
|
||||
return selectList(DiscountProductDO::getActivityId, activityId);
|
||||
}
|
||||
|
||||
default List<DiscountProductDO> selectListByActivityId(Collection<Long> activityIds) {
|
||||
return selectList(DiscountProductDO::getActivityId, activityIds);
|
||||
}
|
||||
|
||||
|
||||
List<DiscountProductDO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public interface DiscountActivityService {
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void closeRewardActivity(Long id);
|
||||
void closeDiscountActivity(Long id);
|
||||
|
||||
/**
|
||||
* 删除限时折扣活动
|
||||
@ -81,4 +81,12 @@ public interface DiscountActivityService {
|
||||
*/
|
||||
List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId);
|
||||
|
||||
/**
|
||||
* 获得活动编号,对应对应的商品列表
|
||||
*
|
||||
* @param activityIds 活动编号
|
||||
* @return 活动的商品列表
|
||||
*/
|
||||
List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds);
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
|
||||
@ -20,6 +21,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
@ -41,8 +43,9 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
|
||||
@Override
|
||||
public List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds) {
|
||||
// TODO 芋艿:开启、满足 skuId、日期内
|
||||
return null;
|
||||
// 芋艿:开启、满足 skuId、日期内
|
||||
List<DiscountProductDO> matchDiscountProductList = discountProductMapper.getMatchDiscountProductList(skuIds);
|
||||
return matchDiscountProductList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,7 +69,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId());
|
||||
if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢
|
||||
if (discountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能修改噢
|
||||
throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
// 校验商品是否冲突
|
||||
@ -99,7 +102,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
|
||||
// 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
|
||||
/**
|
||||
* 校验商品是否冲突
|
||||
*
|
||||
@ -111,27 +114,30 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
return;
|
||||
}
|
||||
// 查询商品参加的活动
|
||||
List<DiscountProductDO> discountActivityProductList = null;
|
||||
|
||||
List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
|
||||
List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
|
||||
List<DiscountProductDO> matchDiscountProductList = getMatchDiscountProductList(skuIds);
|
||||
// getRewardProductListBySkuIds(
|
||||
// convertSet(products, DiscountActivityBaseVO.Product::getSkuId),
|
||||
// asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
if (id != null) { // 排除自己这个活动
|
||||
discountActivityProductList.removeIf(product -> id.equals(product.getActivityId()));
|
||||
matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId()));
|
||||
}
|
||||
// 如果非空,则说明冲突
|
||||
if (CollUtil.isNotEmpty(discountActivityProductList)) {
|
||||
if (CollUtil.isNotEmpty(matchDiscountProductList)) {
|
||||
throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeRewardActivity(Long id) {
|
||||
public void closeDiscountActivity(Long id) {
|
||||
// 校验存在
|
||||
DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id);
|
||||
if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END);
|
||||
}
|
||||
|
||||
@ -144,7 +150,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
public void deleteDiscountActivity(Long id) {
|
||||
// 校验存在
|
||||
DiscountActivityDO discountActivity = validateDiscountActivityExists(id);
|
||||
if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢
|
||||
if (!discountActivity.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())) { // 未关闭的活动,不能删除噢
|
||||
throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
|
||||
}
|
||||
|
||||
@ -175,4 +181,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
return discountProductMapper.selectListByActivityId(activityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds) {
|
||||
return discountProductMapper.selectList("activity_id", activityIds);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper">
|
||||
|
||||
|
||||
<select id="getMatchDiscountProductList" resultType="cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO">
|
||||
SELECT pdp.*
|
||||
FROM promotion_discount_product pdp
|
||||
LEFT JOIN promotion_discount_activity pda
|
||||
ON pdp.activity_id = pda.id
|
||||
<where>
|
||||
<if test="skuIds != null and skuIds.size > 0">
|
||||
AND pdp.sku_id in
|
||||
<foreach collection="skuIds" item="skuId" index="index" open="(" close=")" separator=",">
|
||||
#{skuId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND pda.start_time <= CURRENT_TIME AND pda.end_time >= CURRENT_TIME
|
||||
AND pda.`status` = 20
|
||||
AND pda.deleted != 1
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
Loading…
Reference in New Issue
Block a user