Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # pom.xml # yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java # yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java # yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/CrmStatisticsPerformanceController.java # yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/performance/CrmStatisticsPerformanceReqVO.java # yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java # yudao-module-mall/yudao-module-promotion/pom.xml # yudao-module-mall/yudao-module-trade/pom.xml # yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java # yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthRegisterReqVO.java # yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||
|
||||
/**
|
||||
* 砍价活动 Api 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface BargainActivityApi {
|
||||
|
||||
/**
|
||||
* 更新砍价活动库存
|
||||
*
|
||||
* @param id 砍价活动编号
|
||||
* @param count 购买数量
|
||||
*/
|
||||
void updateBargainActivityStock(Long id, Integer count);
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 砍价活动 Api 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BargainActivityApiImpl implements BargainActivityApi {
|
||||
|
||||
@Resource
|
||||
private BargainActivityService bargainActivityService;
|
||||
|
||||
@Override
|
||||
public void updateBargainActivityStock(Long id, Integer count) {
|
||||
bargainActivityService.updateBargainActivityStock(id, count);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||
|
||||
/**
|
||||
* 砍价记录 API 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface BargainRecordApi {
|
||||
|
||||
/**
|
||||
* 【下单前】校验是否参与砍价活动
|
||||
* <p>
|
||||
* 如果校验失败,则抛出业务异常
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param bargainRecordId 砍价活动编号
|
||||
* @param skuId SKU 编号
|
||||
* @return 砍价信息
|
||||
*/
|
||||
BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
|
||||
|
||||
/**
|
||||
* 更新砍价记录的订单编号
|
||||
*
|
||||
* 在砍价成功后,用户发起订单后,会记录该订单编号
|
||||
*
|
||||
* @param id 砍价记录编号
|
||||
* @param orderId 订单编号
|
||||
*/
|
||||
void updateBargainRecordOrderId(Long id, Long orderId);
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 砍价活动 API 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class BargainRecordApiImpl implements BargainRecordApi {
|
||||
|
||||
@Resource
|
||||
private BargainRecordService bargainRecordService;
|
||||
|
||||
@Override
|
||||
public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
|
||||
return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBargainRecordOrderId(Long id, Long orderId) {
|
||||
bargainRecordService.updateBargainRecordOrderId(id, orderId);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 校验参与砍价 Response DTO
|
||||
*/
|
||||
@Data
|
||||
public class BargainValidateJoinRespDTO {
|
||||
|
||||
/**
|
||||
* 砍价活动编号
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 砍价活动名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 砍价金额
|
||||
*/
|
||||
private Integer bargainPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 拼团记录 API 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface CombinationRecordApi {
|
||||
|
||||
/**
|
||||
* 校验是否满足拼团条件
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param activityId 活动编号
|
||||
* @param headId 团长编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量
|
||||
*/
|
||||
void validateCombinationRecord(Long userId, Long activityId, Long headId, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 创建开团记录
|
||||
*
|
||||
* @param reqDTO 请求 DTO
|
||||
* @return 拼团信息
|
||||
*/
|
||||
CombinationRecordCreateRespDTO createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 基于订单编号,查询拼团记录
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param orderId 订单编号
|
||||
* @return 拼团记录
|
||||
*/
|
||||
CombinationRecordRespDTO getCombinationRecordByOrderId(Long userId, Long orderId);
|
||||
|
||||
/**
|
||||
* 【下单前】校验是否满足拼团活动条件
|
||||
*
|
||||
* 如果校验失败,则抛出业务异常
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param activityId 活动编号
|
||||
* @param headId 团长编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量
|
||||
* @return 拼团信息
|
||||
*/
|
||||
CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId,
|
||||
Long skuId, Integer count);
|
||||
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 拼团活动 API 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CombinationRecordApiImpl implements CombinationRecordApi {
|
||||
|
||||
@Resource
|
||||
private CombinationRecordService combinationRecordService;
|
||||
|
||||
@Override
|
||||
public void validateCombinationRecord(Long userId, Long activityId, Long headId, Long skuId, Integer count) {
|
||||
combinationRecordService.validateCombinationRecord(userId, activityId, headId, skuId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombinationRecordCreateRespDTO createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
|
||||
return CombinationActivityConvert.INSTANCE.convert4(combinationRecordService.createCombinationRecord(reqDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombinationRecordRespDTO getCombinationRecordByOrderId(Long userId, Long orderId) {
|
||||
CombinationRecordDO record = combinationRecordService.getCombinationRecord(userId, orderId);
|
||||
return BeanUtils.toBean(record, CombinationRecordRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, Long skuId, Integer count) {
|
||||
return combinationRecordService.validateJoinCombination(userId, activityId, headId, skuId, count);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 拼团记录的创建 Request DTO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CombinationRecordCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 拼团活动编号
|
||||
*/
|
||||
@NotNull(message = "拼团活动编号不能为空")
|
||||
private Long activityId;
|
||||
/**
|
||||
* spu 编号
|
||||
*/
|
||||
@NotNull(message = "spu 编号不能为空")
|
||||
private Long spuId;
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
@NotNull(message = "sku 编号不能为空")
|
||||
private Long skuId;
|
||||
/**
|
||||
* 购买的商品数量
|
||||
*/
|
||||
@NotNull(message = "购买数量不能为空")
|
||||
private Integer count;
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
@NotNull(message = "订单编号不能为空")
|
||||
private Long orderId;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
/**
|
||||
* 团长编号
|
||||
*/
|
||||
private Long headId;
|
||||
/**
|
||||
* 拼团商品单价
|
||||
*/
|
||||
@NotNull(message = "拼团商品单价不能为空")
|
||||
private Integer combinationPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 拼团记录的创建 Response DTO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CombinationRecordCreateRespDTO {
|
||||
|
||||
/**
|
||||
* 拼团活动编号
|
||||
*
|
||||
* 关联 CombinationActivityDO 的 id 字段
|
||||
*/
|
||||
private Long combinationActivityId;
|
||||
/**
|
||||
* 拼团团长编号
|
||||
*
|
||||
* 关联 CombinationRecordDO 的 headId 字段
|
||||
*/
|
||||
private Long combinationHeadId;
|
||||
/**
|
||||
* 拼团记录编号
|
||||
*
|
||||
* 关联 CombinationRecordDO 的 id 字段
|
||||
*/
|
||||
private Long combinationRecordId;
|
||||
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination.dto;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 拼团记录 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class CombinationRecordRespDTO {
|
||||
|
||||
/**
|
||||
* 编号,主键自增
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 拼团活动编号
|
||||
*
|
||||
* 关联 CombinationActivityDO 的 id 字段
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 拼团商品单价
|
||||
*
|
||||
* 冗余 CombinationProductDO 的 combinationPrice 字段
|
||||
*/
|
||||
private Integer combinationPrice;
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* 商品名字
|
||||
*/
|
||||
private String spuName;
|
||||
/**
|
||||
* 商品图片
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* SKU 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
/**
|
||||
* 购买的商品数量
|
||||
*/
|
||||
private Integer count;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 团长编号
|
||||
*/
|
||||
private Long headId;
|
||||
/**
|
||||
* 开团状态
|
||||
*
|
||||
* 关联 {@link CombinationRecordStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 开团需要人数
|
||||
*
|
||||
* 关联 CombinationActivityDO 的 userSize 字段
|
||||
*/
|
||||
private Integer userSize;
|
||||
/**
|
||||
* 已加入拼团人数
|
||||
*/
|
||||
private Integer userCount;
|
||||
/**
|
||||
* 是否虚拟成团
|
||||
*/
|
||||
private Boolean virtualGroup;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private LocalDateTime expireTime;
|
||||
/**
|
||||
* 开始时间 (订单付款后开始的时间)
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
/**
|
||||
* 结束时间(成团时间/失败时间)
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 校验参与拼团 Response DTO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CombinationValidateJoinRespDTO {
|
||||
|
||||
/**
|
||||
* 砍价活动编号
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 砍价活动名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 拼团金额
|
||||
*/
|
||||
private Integer combinationPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.coupon;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 优惠劵 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CouponApi {
|
||||
|
||||
/**
|
||||
* 获得用户的优惠劵列表
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param status 优惠劵状态
|
||||
* @return 优惠劵列表
|
||||
*/
|
||||
List<CouponRespDTO> getCouponListByUserId(Long userId, Integer status);
|
||||
|
||||
/**
|
||||
* 使用优惠劵
|
||||
*
|
||||
* @param useReqDTO 使用请求
|
||||
*/
|
||||
void useCoupon(@Valid CouponUseReqDTO useReqDTO);
|
||||
|
||||
/**
|
||||
* 退还已使用的优惠券
|
||||
*
|
||||
* @param id 优惠券编号
|
||||
*/
|
||||
void returnUsedCoupon(Long id);
|
||||
|
||||
/**
|
||||
* 【管理员】给指定用户批量发送优惠券
|
||||
*
|
||||
* @param giveCoupons key: 优惠劵模版编号,value:对应的数量
|
||||
* @param userId 用户编号
|
||||
* @return 优惠券编号列表
|
||||
*/
|
||||
List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId);
|
||||
|
||||
/**
|
||||
* 【管理员】作废指定用户的指定优惠劵
|
||||
*
|
||||
* @param giveCouponIds 赠送的优惠券编号
|
||||
* @param userId 用户编号
|
||||
*/
|
||||
void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId);
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.coupon;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 优惠劵 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class CouponApiImpl implements CouponApi {
|
||||
|
||||
@Resource
|
||||
private CouponService couponService;
|
||||
|
||||
@Override
|
||||
public List<CouponRespDTO> getCouponListByUserId(Long userId, Integer status) {
|
||||
return BeanUtils.toBean(couponService.getCouponList(userId, status), CouponRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useCoupon(CouponUseReqDTO useReqDTO) {
|
||||
couponService.useCoupon(useReqDTO.getId(), useReqDTO.getUserId(),
|
||||
useReqDTO.getOrderId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnUsedCoupon(Long id) {
|
||||
couponService.returnUsedCoupon(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId) {
|
||||
return couponService.takeCouponsByAdmin(giveCoupons, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) {
|
||||
couponService.invalidateCouponsByAdmin(giveCouponIds, userId);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.coupon.dto;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优惠劵 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class CouponRespDTO {
|
||||
|
||||
// ========== 基本信息 BEGIN ==========
|
||||
/**
|
||||
* 优惠劵编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 优惠劵模板编号
|
||||
*/
|
||||
private Integer templateId;
|
||||
/**
|
||||
* 优惠劵名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 优惠码状态
|
||||
*
|
||||
* 枚举 {@link CouponStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
// ========== 基本信息 END ==========
|
||||
|
||||
// ========== 领取情况 BEGIN ==========
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 关联 MemberUserDO 的 id 字段
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 领取类型
|
||||
*
|
||||
* 枚举 {@link CouponTakeTypeEnum}
|
||||
*/
|
||||
private Integer takeType;
|
||||
// ========== 领取情况 END ==========
|
||||
|
||||
// ========== 使用规则 BEGIN ==========
|
||||
/**
|
||||
* 是否设置满多少金额可用,单位:分
|
||||
*/
|
||||
private Integer usePrice;
|
||||
/**
|
||||
* 生效开始时间
|
||||
*/
|
||||
private LocalDateTime validStartTime;
|
||||
/**
|
||||
* 生效结束时间
|
||||
*/
|
||||
private LocalDateTime validEndTime;
|
||||
/**
|
||||
* 商品范围
|
||||
*/
|
||||
private Integer productScope;
|
||||
/**
|
||||
* 商品范围编号的数组
|
||||
*/
|
||||
private List<Long> productScopeValues;
|
||||
// ========== 使用规则 END ==========
|
||||
|
||||
// ========== 使用效果 BEGIN ==========
|
||||
/**
|
||||
* 折扣类型
|
||||
*/
|
||||
private Integer discountType;
|
||||
/**
|
||||
* 折扣百分比
|
||||
*/
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 优惠金额,单位:分
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
/**
|
||||
* 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效
|
||||
*/
|
||||
private Integer discountLimitPrice;
|
||||
// ========== 使用效果 END ==========
|
||||
|
||||
// ========== 使用情况 BEGIN ==========
|
||||
/**
|
||||
* 使用订单号
|
||||
*/
|
||||
private Long useOrderId;
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private LocalDateTime useTime;
|
||||
|
||||
// ========== 使用情况 END ==========
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.coupon.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 优惠劵使用 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class CouponUseReqDTO {
|
||||
|
||||
/**
|
||||
* 优惠劵编号
|
||||
*/
|
||||
@NotNull(message = "优惠劵编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
@NotNull(message = "订单编号不能为空")
|
||||
private Long orderId;
|
||||
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.discount;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限时折扣 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface DiscountActivityApi {
|
||||
|
||||
/**
|
||||
* 获得 skuId 商品匹配的的限时折扣信息
|
||||
*
|
||||
* @param skuIds 商品 SKU 编号数组
|
||||
* @return 限时折扣信息
|
||||
*/
|
||||
List<DiscountProductRespDTO> getMatchDiscountProductListBySkuIds(Collection<Long> skuIds);
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限时折扣 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class DiscountActivityApiImpl implements DiscountActivityApi {
|
||||
|
||||
@Resource
|
||||
private DiscountActivityService discountActivityService;
|
||||
|
||||
@Override
|
||||
public List<DiscountProductRespDTO> getMatchDiscountProductListBySkuIds(Collection<Long> skuIds) {
|
||||
List<DiscountProductDO> list = discountActivityService.getMatchDiscountProductListBySkuIds(skuIds);
|
||||
return BeanUtils.toBean(list, DiscountProductRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.discount.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 限时折扣活动商品 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class DiscountProductRespDTO {
|
||||
|
||||
/**
|
||||
* 编号,主键自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
/**
|
||||
* 折扣类型
|
||||
*/
|
||||
private Integer discountType;
|
||||
/**
|
||||
* 折扣百分比
|
||||
*/
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 优惠金额,单位:分
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
|
||||
// ========== 活动字段 ==========
|
||||
/**
|
||||
* 限时折扣活动的编号
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 活动标题
|
||||
*/
|
||||
private String activityName;
|
||||
/**
|
||||
* 活动开始时间点
|
||||
*/
|
||||
private LocalDateTime activityStartTime;
|
||||
/**
|
||||
* 活动结束时间点
|
||||
*/
|
||||
private LocalDateTime activityEndTime;
|
||||
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* promotion API 包,定义并实现提供给其它模块的 API
|
||||
*/
|
||||
package cn.iocoder.yudao.module.promotion.api;
|
@@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.point;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO;
|
||||
|
||||
/**
|
||||
* 积分商城活动 API 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface PointActivityApi {
|
||||
|
||||
/**
|
||||
* 【下单前】校验是否参与积分商城活动
|
||||
*
|
||||
* 如果校验失败,则抛出业务异常
|
||||
*
|
||||
* @param activityId 活动编号
|
||||
* @param skuId SKU 编号
|
||||
* @param count 数量
|
||||
* @return 积分商城商品信息
|
||||
*/
|
||||
PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 更新积分商城商品库存(减少)
|
||||
*
|
||||
* @param id 活动编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量(正数)
|
||||
*/
|
||||
void updatePointStockDecr(Long id, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 更新积分商城商品库存(增加)
|
||||
*
|
||||
* @param id 活动编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量(正数)
|
||||
*/
|
||||
void updatePointStockIncr(Long id, Long skuId, Integer count);
|
||||
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.point;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.point.dto.PointValidateJoinRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.point.PointActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 积分商城活动 Api 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class PointActivityApiImpl implements PointActivityApi {
|
||||
|
||||
@Resource
|
||||
private PointActivityService pointActivityService;
|
||||
|
||||
@Override
|
||||
public PointValidateJoinRespDTO validateJoinPointActivity(Long activityId, Long skuId, Integer count) {
|
||||
return pointActivityService.validateJoinPointActivity(activityId, skuId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePointStockDecr(Long id, Long skuId, Integer count) {
|
||||
pointActivityService.updatePointStockDecr(id, skuId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePointStockIncr(Long id, Long skuId, Integer count) {
|
||||
pointActivityService.updatePointStockIncr(id, skuId, count);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.point.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 校验参与积分商城 Response DTO
|
||||
*/
|
||||
@Data
|
||||
public class PointValidateJoinRespDTO {
|
||||
|
||||
/**
|
||||
* 可兑换次数
|
||||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 所需兑换积分
|
||||
*/
|
||||
private Integer point;
|
||||
/**
|
||||
* 所需兑换金额,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.reward;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 满减送活动 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface RewardActivityApi {
|
||||
|
||||
/**
|
||||
* 获得 spuId 商品匹配的的满减送活动列表
|
||||
*
|
||||
* @param spuIds SPU 编号
|
||||
* @return 满减送活动列表
|
||||
*/
|
||||
List<RewardActivityMatchRespDTO> getMatchRewardActivityListBySpuIds(Collection<Long> spuIds);
|
||||
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.reward;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 满减送活动 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class RewardActivityApiImpl implements RewardActivityApi {
|
||||
|
||||
@Resource
|
||||
private RewardActivityService rewardActivityService;
|
||||
|
||||
@Override
|
||||
public List<RewardActivityMatchRespDTO> getMatchRewardActivityListBySpuIds(Collection<Long> spuIds) {
|
||||
return rewardActivityService.getMatchRewardActivityListBySpuIds(spuIds);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.reward.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 满减送活动的匹配 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class RewardActivityMatchRespDTO {
|
||||
|
||||
/**
|
||||
* 匹配的 SPU 数组
|
||||
*/
|
||||
private List<Long> spuIds;
|
||||
|
||||
/**
|
||||
* 活动编号,主键自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 活动标题
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 条件类型
|
||||
*
|
||||
* 枚举 {@link PromotionConditionTypeEnum}
|
||||
*/
|
||||
private Integer conditionType;
|
||||
/**
|
||||
* 商品范围
|
||||
*
|
||||
* 枚举 {@link PromotionProductScopeEnum}
|
||||
*/
|
||||
private Integer productScope;
|
||||
/**
|
||||
* 商品 SPU 编号的数组
|
||||
*/
|
||||
private List<Long> productScopeValues;
|
||||
/**
|
||||
* 优惠规则的数组
|
||||
*/
|
||||
private List<Rule> rules;
|
||||
|
||||
/**
|
||||
* 优惠规则
|
||||
*/
|
||||
@Data
|
||||
public static class Rule implements Serializable {
|
||||
|
||||
/**
|
||||
* 优惠门槛
|
||||
*
|
||||
* 1. 满 N 元,单位:分
|
||||
* 2. 满 N 件
|
||||
*/
|
||||
private Integer limit;
|
||||
/**
|
||||
* 优惠价格,单位:分
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
/**
|
||||
* 是否包邮
|
||||
*/
|
||||
private Boolean freeDelivery;
|
||||
/**
|
||||
* 赠送的积分
|
||||
*/
|
||||
private Integer point;
|
||||
/**
|
||||
* 赠送的优惠劵
|
||||
*
|
||||
* key: 优惠劵模版编号
|
||||
* value:对应的优惠券数量
|
||||
*
|
||||
* 目的:用于订单支付后赠送优惠券
|
||||
*/
|
||||
private Map<Long, Integer> giveCouponTemplateCounts;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*
|
||||
* 通过 {@link #limit}、{@link #discountPrice} 等字段进行拼接
|
||||
*/
|
||||
private String description;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.seckill;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillValidateJoinRespDTO;
|
||||
|
||||
/**
|
||||
* 秒杀活动 API 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface SeckillActivityApi {
|
||||
|
||||
/**
|
||||
* 更新秒杀库存(减少)
|
||||
*
|
||||
* @param id 活动编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量(正数)
|
||||
*/
|
||||
void updateSeckillStockDecr(Long id, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 更新秒杀库存(增加)
|
||||
*
|
||||
* @param id 活动编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量(正数)
|
||||
*/
|
||||
void updateSeckillStockIncr(Long id, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 【下单前】校验是否参与秒杀活动
|
||||
*
|
||||
* 如果校验失败,则抛出业务异常
|
||||
*
|
||||
* @param activityId 活动编号
|
||||
* @param skuId SKU 编号
|
||||
* @param count 数量
|
||||
* @return 秒杀信息
|
||||
*/
|
||||
SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
|
||||
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.seckill;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillValidateJoinRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 秒杀活动接口 Api 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class SeckillActivityApiImpl implements SeckillActivityApi {
|
||||
|
||||
@Resource
|
||||
private SeckillActivityService activityService;
|
||||
|
||||
@Override
|
||||
public void updateSeckillStockDecr(Long id, Long skuId, Integer count) {
|
||||
activityService.updateSeckillStockDecr(id, skuId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSeckillStockIncr(Long id, Long skuId, Integer count) {
|
||||
activityService.updateSeckillStockIncr(id, skuId, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count) {
|
||||
return activityService.validateJoinSeckill(activityId, skuId, count);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.seckill.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 校验参与秒杀 Response DTO
|
||||
*/
|
||||
@Data
|
||||
public class SeckillValidateJoinRespDTO {
|
||||
|
||||
/**
|
||||
* 秒杀活动名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 总限购数量
|
||||
*
|
||||
* 目的:目前只有 trade 有具体下单的数据,需要交给 trade 价格计算使用
|
||||
*/
|
||||
private Integer totalLimitCount;
|
||||
|
||||
/**
|
||||
* 秒杀金额
|
||||
*/
|
||||
private Integer seckillPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.article.ArticleCategoryConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.article.ArticleCategoryService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 文章分类")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/article-category")
|
||||
@Validated
|
||||
public class ArticleCategoryController {
|
||||
|
||||
@Resource
|
||||
private ArticleCategoryService articleCategoryService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文章分类")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article-category:create')")
|
||||
public CommonResult<Long> createArticleCategory(@Valid @RequestBody ArticleCategoryCreateReqVO createReqVO) {
|
||||
return success(articleCategoryService.createArticleCategory(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新文章分类")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article-category:update')")
|
||||
public CommonResult<Boolean> updateArticleCategory(@Valid @RequestBody ArticleCategoryUpdateReqVO updateReqVO) {
|
||||
articleCategoryService.updateArticleCategory(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文章分类")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article-category:delete')")
|
||||
public CommonResult<Boolean> deleteArticleCategory(@RequestParam("id") Long id) {
|
||||
articleCategoryService.deleteArticleCategory(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文章分类")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article-category:query')")
|
||||
public CommonResult<ArticleCategoryRespVO> getArticleCategory(@RequestParam("id") Long id) {
|
||||
ArticleCategoryDO category = articleCategoryService.getArticleCategory(id);
|
||||
return success(ArticleCategoryConvert.INSTANCE.convert(category));
|
||||
}
|
||||
|
||||
@GetMapping("/list-all-simple")
|
||||
@Operation(summary = "获取文章分类精简信息列表", description = "只包含被开启的文章分类,主要用于前端的下拉选项")
|
||||
public CommonResult<List<ArticleCategorySimpleRespVO>> getSimpleDeptList() {
|
||||
// 获得分类列表,只要开启状态的
|
||||
List<ArticleCategoryDO> list = articleCategoryService.getArticleCategoryListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// 降序排序后,返回给前端
|
||||
list.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed());
|
||||
return success(ArticleCategoryConvert.INSTANCE.convertList03(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得文章分类分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article-category:query')")
|
||||
public CommonResult<PageResult<ArticleCategoryRespVO>> getArticleCategoryPage(@Valid ArticleCategoryPageReqVO pageVO) {
|
||||
PageResult<ArticleCategoryDO> pageResult = articleCategoryService.getArticleCategoryPage(pageVO);
|
||||
return success(ArticleCategoryConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticlePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.article.ArticleConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.article.ArticleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 文章管理")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/article")
|
||||
@Validated
|
||||
public class ArticleController {
|
||||
|
||||
@Resource
|
||||
private ArticleService articleService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建文章管理")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article:create')")
|
||||
public CommonResult<Long> createArticle(@Valid @RequestBody ArticleCreateReqVO createReqVO) {
|
||||
return success(articleService.createArticle(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新文章管理")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article:update')")
|
||||
public CommonResult<Boolean> updateArticle(@Valid @RequestBody ArticleUpdateReqVO updateReqVO) {
|
||||
articleService.updateArticle(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除文章管理")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article:delete')")
|
||||
public CommonResult<Boolean> deleteArticle(@RequestParam("id") Long id) {
|
||||
articleService.deleteArticle(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得文章管理")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article:query')")
|
||||
public CommonResult<ArticleRespVO> getArticle(@RequestParam("id") Long id) {
|
||||
ArticleDO article = articleService.getArticle(id);
|
||||
return success(ArticleConvert.INSTANCE.convert(article));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得文章管理分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:article:query')")
|
||||
public CommonResult<PageResult<ArticleRespVO>> getArticlePage(@Valid ArticlePageReqVO pageVO) {
|
||||
PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageVO);
|
||||
return success(ArticleConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 文章管理 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class ArticleBaseVO {
|
||||
|
||||
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15458")
|
||||
@NotNull(message = "文章分类编号不能为空")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "关联商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22378")
|
||||
@NotNull(message = "关联商品不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "文章标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个标题")
|
||||
@NotNull(message = "文章标题不能为空")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文章作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
private String author;
|
||||
|
||||
@Schema(description = "文章封面图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
|
||||
@NotNull(message = "文章封面图片地址不能为空")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "文章简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个简介")
|
||||
private String introduction;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否热门(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否热门(小程序)不能为空")
|
||||
private Boolean recommendHot;
|
||||
|
||||
@Schema(description = "是否轮播图(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否轮播图(小程序)不能为空")
|
||||
private Boolean recommendBanner;
|
||||
|
||||
@Schema(description = "文章内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是文章内容")
|
||||
@NotNull(message = "文章内容不能为空")
|
||||
private String content;
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 文章管理创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleCreateReqVO extends ArticleBaseVO {
|
||||
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 文章管理分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticlePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "文章分类编号", example = "15458")
|
||||
private Long categoryId;
|
||||
|
||||
@Schema(description = "关联商品编号", example = "22378")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "文章标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "文章作者")
|
||||
private String author;
|
||||
|
||||
@Schema(description = "状态", example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否热门(小程序)")
|
||||
private Boolean recommendHot;
|
||||
|
||||
@Schema(description = "是否轮播图(小程序)")
|
||||
private Boolean recommendBanner;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 文章管理 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleRespVO extends ArticleBaseVO {
|
||||
|
||||
@Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "99999")
|
||||
private Integer browseCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 文章管理更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleUpdateReqVO extends ArticleBaseVO {
|
||||
|
||||
@Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
|
||||
@NotNull(message = "文章编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 文章分类 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class ArticleCategoryBaseVO {
|
||||
|
||||
@Schema(description = "文章分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "秒杀")
|
||||
@NotNull(message = "文章分类名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "图标地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 文章分类创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleCategoryCreateReqVO extends ArticleCategoryBaseVO {
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 文章分类分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleCategoryPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "文章分类名称", example = "秒杀")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 文章分类 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleCategoryRespVO extends ArticleCategoryBaseVO {
|
||||
|
||||
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 文章分类精简信息 Response VO")
|
||||
@Data
|
||||
public class ArticleCategorySimpleRespVO {
|
||||
|
||||
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "文章分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "秒杀")
|
||||
private String name;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 文章分类更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ArticleCategoryUpdateReqVO extends ArticleCategoryBaseVO {
|
||||
|
||||
@Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "19490")
|
||||
@NotNull(message = "文章分类编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.banner.BannerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - Banner 管理")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/banner")
|
||||
@Validated
|
||||
public class BannerController {
|
||||
|
||||
@Resource
|
||||
private BannerService bannerService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建 Banner")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:banner:create')")
|
||||
public CommonResult<Long> createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) {
|
||||
return success(bannerService.createBanner(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新 Banner")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:banner:update')")
|
||||
public CommonResult<Boolean> updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) {
|
||||
bannerService.updateBanner(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除 Banner")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:banner:delete')")
|
||||
public CommonResult<Boolean> deleteBanner(@RequestParam("id") Long id) {
|
||||
bannerService.deleteBanner(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 Banner")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:banner:query')")
|
||||
public CommonResult<BannerRespVO> getBanner(@RequestParam("id") Long id) {
|
||||
BannerDO banner = bannerService.getBanner(id);
|
||||
return success(BannerConvert.INSTANCE.convert(banner));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 Banner 分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:banner:query')")
|
||||
public CommonResult<PageResult<BannerRespVO>> getBannerPage(@Valid BannerPageReqVO pageVO) {
|
||||
PageResult<BannerDO> pageResult = bannerService.getBannerPage(pageVO);
|
||||
return success(BannerConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.banner.BannerPositionEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Banner Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
* @author xia
|
||||
*/
|
||||
@Data
|
||||
public class BannerBaseVO {
|
||||
|
||||
@Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "标题不能为空")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "跳转链接不能为空")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "图片地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "图片地址不能为空")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "position", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "position 不能为空")
|
||||
@InEnum(BannerPositionEnum.class)
|
||||
private Integer position;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String memo;
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* @author xia
|
||||
*/
|
||||
@Schema(description = "管理后台 - Banner 创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BannerCreateReqVO extends BannerBaseVO {
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - Banner 分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BannerPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "标题", example = "这是一个标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - Banner Response VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class BannerRespVO extends BannerBaseVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author xia
|
||||
*/
|
||||
@Schema(description = "管理后台 - Banner更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BannerUpdateReqVO extends BannerBaseVO {
|
||||
|
||||
@Schema(description = "banner 编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "banner 编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
|
||||
|
||||
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.bargain.vo.activity.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainHelpService;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - 砍价活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/bargain-activity")
|
||||
@Validated
|
||||
public class BargainActivityController {
|
||||
|
||||
@Resource
|
||||
private BargainActivityService bargainActivityService;
|
||||
@Resource
|
||||
private BargainRecordService bargainRecordService;
|
||||
@Resource
|
||||
private BargainHelpService bargainHelpService;
|
||||
|
||||
@Resource
|
||||
private ProductSpuApi spuApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建砍价活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:create')")
|
||||
public CommonResult<Long> createBargainActivity(@Valid @RequestBody BargainActivityCreateReqVO createReqVO) {
|
||||
return success(bargainActivityService.createBargainActivity(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新砍价活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:update')")
|
||||
public CommonResult<Boolean> updateBargainActivity(@Valid @RequestBody BargainActivityUpdateReqVO updateReqVO) {
|
||||
bargainActivityService.updateBargainActivity(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@Operation(summary = "关闭砍价活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:close')")
|
||||
public CommonResult<Boolean> closeSeckillActivity(@RequestParam("id") Long id) {
|
||||
bargainActivityService.closeBargainActivityById(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除砍价活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:delete')")
|
||||
public CommonResult<Boolean> deleteBargainActivity(@RequestParam("id") Long id) {
|
||||
bargainActivityService.deleteBargainActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得砍价活动")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
|
||||
public CommonResult<BargainActivityRespVO> getBargainActivity(@RequestParam("id") Long id) {
|
||||
return success(BargainActivityConvert.INSTANCE.convert(bargainActivityService.getBargainActivity(id)));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得砍价活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
|
||||
public CommonResult<PageResult<BargainActivityPageItemRespVO>> getBargainActivityPage(
|
||||
@Valid BargainActivityPageReqVO pageVO) {
|
||||
// 查询砍价活动
|
||||
PageResult<BargainActivityDO> pageResult = bargainActivityService.getBargainActivityPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), BargainActivityDO::getSpuId));
|
||||
// 统计数据
|
||||
Collection<Long> activityIds = convertList(pageResult.getList(), BargainActivityDO::getId);
|
||||
Map<Long, Integer> recordUserCountMap = bargainRecordService.getBargainRecordUserCountMap(activityIds, null);
|
||||
Map<Long, Integer> recordSuccessUserCountMap = bargainRecordService.getBargainRecordUserCountMap(activityIds,
|
||||
BargainRecordStatusEnum.SUCCESS.getStatus());
|
||||
Map<Long, Integer> helpUserCountMap = bargainHelpService.getBargainHelpUserCountMapByActivity(activityIds);
|
||||
return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList,
|
||||
recordUserCountMap, recordSuccessUserCountMap, helpUserCountMap));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
|
||||
|
||||
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.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help.BargainHelpPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help.BargainHelpRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.bargain.BargainHelpConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainHelpService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 砍价助力")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/bargain-help")
|
||||
@Validated
|
||||
public class BargainHelpController {
|
||||
|
||||
@Resource
|
||||
private BargainHelpService bargainHelpService;
|
||||
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得砍价助力分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-help:query')")
|
||||
public CommonResult<PageResult<BargainHelpRespVO>> getBargainHelpPage(@Valid BargainHelpPageReqVO pageVO) {
|
||||
PageResult<BargainHelpDO> pageResult = bargainHelpService.getBargainHelpPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
|
||||
convertSet(pageResult.getList(), BargainHelpDO::getUserId));
|
||||
return success(BargainHelpConvert.INSTANCE.convertPage(pageResult, userMap));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
|
||||
|
||||
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.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.recrod.BargainRecordPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.recrod.BargainRecordPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.bargain.BargainRecordConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainHelpService;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 砍价记录")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/bargain-record")
|
||||
@Validated
|
||||
public class BargainRecordController {
|
||||
|
||||
@Resource
|
||||
private BargainRecordService bargainRecordService;
|
||||
@Resource
|
||||
private BargainActivityService bargainActivityService;
|
||||
@Resource
|
||||
private BargainHelpService bargainHelpService;
|
||||
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得砍价记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:bargain-record:query')")
|
||||
public CommonResult<PageResult<BargainRecordPageItemRespVO>> getBargainRecordPage(@Valid BargainRecordPageReqVO pageVO) {
|
||||
PageResult<BargainRecordDO> pageResult = bargainRecordService.getBargainRecordPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
|
||||
convertSet(pageResult.getList(), BargainRecordDO::getUserId));
|
||||
List<BargainActivityDO> activityList = bargainActivityService.getBargainActivityList(
|
||||
convertSet(pageResult.getList(), BargainRecordDO::getActivityId));
|
||||
Map<Long, Integer> helpCountMap = bargainHelpService.getBargainHelpUserCountMapByRecord(
|
||||
convertSet(pageResult.getList(), BargainRecordDO::getId));
|
||||
return success(BargainRecordConvert.INSTANCE.convertPage(pageResult, helpCountMap, activityList, userMap));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 砍价活动 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class BargainActivityBaseVO {
|
||||
|
||||
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "砍得越多省得越多,是兄弟就来砍我")
|
||||
@NotNull(message = "砍价名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", example = "1")
|
||||
@NotNull(message = "砍价商品不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
|
||||
@NotNull(message = "商品 skuId 不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
|
||||
@NotNull(message = "砍价起始价格不能为空")
|
||||
private Integer bargainFirstPrice;
|
||||
|
||||
@Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
|
||||
@NotNull(message = "砍价底价不能为空")
|
||||
private Integer bargainMinPrice;
|
||||
|
||||
@Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
|
||||
@NotNull(message = "活动库存不能为空")
|
||||
private Integer stock;
|
||||
|
||||
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
|
||||
@NotNull(message = "总限购数量不能为空")
|
||||
private Integer totalLimitCount;
|
||||
|
||||
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
|
||||
@NotNull(message = "活动开始时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
|
||||
@NotNull(message = "活动结束时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "最大助力次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
|
||||
@NotNull(message = "最大助力次数不能为空")
|
||||
private Integer helpMaxCount;
|
||||
|
||||
@Schema(description = "最大帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
|
||||
@NotNull(message = "最大帮砍次数不能为空")
|
||||
private Integer bargainCount;
|
||||
|
||||
@Schema(description = "用户每次砍价的最小金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
|
||||
@NotNull(message = "用户每次砍价的最小金额不能为空")
|
||||
private Integer randomMinPrice;
|
||||
|
||||
@Schema(description = "用户每次砍价的最大金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
|
||||
@NotNull(message = "用户每次砍价的最大金额不能为空")
|
||||
private Integer randomMaxPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainActivityCreateReqVO extends BargainActivityBaseVO {
|
||||
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价活动的分页项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainActivityPageItemRespVO extends BargainActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
|
||||
private String spuName;
|
||||
@Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "活动状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "活动总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
|
||||
private Integer totalStock;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
// ========== 统计字段 ==========
|
||||
|
||||
@Schema(description = "总砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "999")
|
||||
private Integer recordUserCount;
|
||||
|
||||
@Schema(description = "成功砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500")
|
||||
private Integer recordSuccessUserCount;
|
||||
|
||||
@Schema(description = "帮助砍价的用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
|
||||
private Integer helpUserCount;
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价活动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainActivityPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "砍价名称", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "活动状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@Schema(description = "管理后台 - 砍价活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainActivityRespVO extends BargainActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainActivityUpdateReqVO extends BargainActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
@NotNull(message = "活动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 砍价助力 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class BargainHelpBaseVO {
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5402")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "16825")
|
||||
private Long activityId;
|
||||
|
||||
@Schema(description = "砍价记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1800")
|
||||
private Long recordId;
|
||||
|
||||
@Schema(description = "减少砍价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "32300")
|
||||
private Integer reducePrice;
|
||||
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价助力分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainHelpPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "砍价记录编号", example = "1800")
|
||||
private Long recordId;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.help;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价助力 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainHelpRespVO extends BargainHelpBaseVO {
|
||||
|
||||
@Schema(description = "砍价助力编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25860")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
// ========== 用户相关 ==========
|
||||
|
||||
@Schema(description = "用户昵称", example = "老芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
|
||||
private String avatar;
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.recrod;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 砍价记录 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class BargainRecordBaseVO {
|
||||
|
||||
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "22690")
|
||||
@NotNull(message = "砍价活动名称不能为空")
|
||||
private Long activityId;
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9430")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23622")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29950")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "砍价起始价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "31160")
|
||||
@NotNull(message = "砍价起始价格,单位:分不能为空")
|
||||
private Integer bargainFirstPrice;
|
||||
|
||||
@Schema(description = "当前砍价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22743")
|
||||
@NotNull(message = "当前砍价,单位:分不能为空")
|
||||
private Integer bargainPrice;
|
||||
|
||||
@Schema(description = "砍价状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "砍价状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "订单编号", example = "27845")
|
||||
private Long orderId;
|
||||
|
||||
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "结束时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价记录的分页项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainRecordPageItemRespVO extends BargainRecordBaseVO {
|
||||
|
||||
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer helpCount;
|
||||
|
||||
// ========== 用户相关 ==========
|
||||
|
||||
@Schema(description = "用户昵称", example = "老芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
|
||||
private String avatar;
|
||||
|
||||
// ========== 活动相关 ==========
|
||||
|
||||
private BargainActivityRespVO activity;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 砍价记录分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class BargainRecordPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "砍价状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
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.combination.vo.activity.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.hutool.core.collection.CollectionUtil.newArrayList;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 拼团活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/combination-activity")
|
||||
@Validated
|
||||
public class CombinationActivityController {
|
||||
|
||||
@Resource
|
||||
private CombinationActivityService combinationActivityService;
|
||||
@Resource
|
||||
private CombinationRecordService combinationRecordService;
|
||||
|
||||
@Resource
|
||||
private ProductSpuApi productSpuApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建拼团活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:create')")
|
||||
public CommonResult<Long> createCombinationActivity(@Valid @RequestBody CombinationActivityCreateReqVO createReqVO) {
|
||||
return success(combinationActivityService.createCombinationActivity(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新拼团活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:update')")
|
||||
public CommonResult<Boolean> updateCombinationActivity(@Valid @RequestBody CombinationActivityUpdateReqVO updateReqVO) {
|
||||
combinationActivityService.updateCombinationActivity(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@Operation(summary = "关闭拼团活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:close')")
|
||||
public CommonResult<Boolean> closeCombinationActivity(@RequestParam("id") Long id) {
|
||||
combinationActivityService.closeCombinationActivityById(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除拼团活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:delete')")
|
||||
public CommonResult<Boolean> deleteCombinationActivity(@RequestParam("id") Long id) {
|
||||
combinationActivityService.deleteCombinationActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得拼团活动")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
|
||||
public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
|
||||
CombinationActivityDO activity = combinationActivityService.getCombinationActivity(id);
|
||||
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(newArrayList(id));
|
||||
return success(CombinationActivityConvert.INSTANCE.convert(activity, products));
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-ids")
|
||||
@Operation(summary = "获得拼团活动列表,基于活动编号数组")
|
||||
@Parameter(name = "ids", description = "活动编号数组", required = true, example = "[1024, 1025]")
|
||||
public CommonResult<List<CombinationActivityRespVO>> getCombinationActivityListByIds(@RequestParam("ids") List<Long> ids) {
|
||||
// 1. 获得开启的活动列表
|
||||
List<CombinationActivityDO> activityList = combinationActivityService.getCombinationActivityListByIds(ids);
|
||||
activityList.removeIf(activity -> CommonStatusEnum.isDisable(activity.getStatus()));
|
||||
if (CollUtil.isEmpty(activityList)) {
|
||||
return success(Collections.emptyList());
|
||||
}
|
||||
// 2. 拼接返回
|
||||
List<CombinationProductDO> productList = combinationActivityService.getCombinationProductListByActivityIds(
|
||||
convertList(activityList, CombinationActivityDO::getId));
|
||||
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(convertList(activityList, CombinationActivityDO::getSpuId));
|
||||
return success(CombinationActivityConvert.INSTANCE.convertList(activityList, productList, spuList));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得拼团活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
|
||||
public CommonResult<PageResult<CombinationActivityPageItemRespVO>> getCombinationActivityPage(
|
||||
@Valid CombinationActivityPageReqVO pageVO) {
|
||||
// 查询拼团活动
|
||||
PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 统计数据
|
||||
Set<Long> activityIds = convertSet(pageResult.getList(), CombinationActivityDO::getId);
|
||||
Map<Long, Integer> groupCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
|
||||
activityIds, null, CombinationRecordDO.HEAD_ID_GROUP);
|
||||
Map<Long, Integer> groupSuccessCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
|
||||
activityIds, CombinationRecordStatusEnum.SUCCESS.getStatus(), CombinationRecordDO.HEAD_ID_GROUP);
|
||||
Map<Long, Integer> recordCountMap = combinationRecordService.getCombinationRecordCountMapByActivity(
|
||||
activityIds, null, null);
|
||||
// 拼接数据
|
||||
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(
|
||||
convertSet(pageResult.getList(), CombinationActivityDO::getId));
|
||||
List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(
|
||||
convertSet(pageResult.getList(), CombinationActivityDO::getSpuId));
|
||||
return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products,
|
||||
groupCountMap, groupSuccessCountMap, recordCountMap, spus));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod.CombinationRecordPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod.CombinationRecordReqPageVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod.CombinationRecordSummaryVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 拼团记录")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/combination-record")
|
||||
@Validated
|
||||
public class CombinationRecordController {
|
||||
|
||||
@Resource
|
||||
private CombinationActivityService combinationActivityService;
|
||||
@Resource
|
||||
@Lazy
|
||||
private CombinationRecordService combinationRecordService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得拼团记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-record:query')")
|
||||
public CommonResult<PageResult<CombinationRecordPageItemRespVO>> getCombinationRecordPage(
|
||||
@Valid CombinationRecordReqPageVO pageVO) {
|
||||
PageResult<CombinationRecordDO> recordPage = combinationRecordService.getCombinationRecordPage(pageVO);
|
||||
// 拼接数据
|
||||
List<CombinationActivityDO> activities = combinationActivityService.getCombinationActivityListByIds(
|
||||
convertSet(recordPage.getList(), CombinationRecordDO::getActivityId));
|
||||
List<CombinationProductDO> products = combinationActivityService.getCombinationProductListByActivityIds(
|
||||
convertSet(recordPage.getList(), CombinationRecordDO::getActivityId));
|
||||
return success(CombinationActivityConvert.INSTANCE.convert(recordPage, activities, products));
|
||||
}
|
||||
|
||||
@GetMapping("/get-summary")
|
||||
@Operation(summary = "获得拼团记录的概要信息", description = "用于拼团记录页面展示")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:combination-record:query')")
|
||||
public CommonResult<CombinationRecordSummaryVO> getCombinationRecordSummary() {
|
||||
CombinationRecordSummaryVO summaryVO = new CombinationRecordSummaryVO();
|
||||
summaryVO.setUserCount(combinationRecordService.getCombinationUserCount()); // 获取拼团用户参与数量
|
||||
summaryVO.setSuccessCount(combinationRecordService.getCombinationRecordCount( // 获取成团记录
|
||||
CombinationRecordStatusEnum.SUCCESS.getStatus(), null, CombinationRecordDO.HEAD_ID_GROUP));
|
||||
summaryVO.setVirtualGroupCount(combinationRecordService.getCombinationRecordCount(// 获取虚拟成团记录
|
||||
null, Boolean.TRUE, CombinationRecordDO.HEAD_ID_GROUP));
|
||||
return success(summaryVO);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 拼团活动 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CombinationActivityBaseVO {
|
||||
|
||||
@Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
|
||||
@NotNull(message = "拼团名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "拼团商品不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
|
||||
@NotNull(message = "总限购数量不能为空")
|
||||
private Integer totalLimitCount;
|
||||
|
||||
@Schema(description = "单次限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "28265")
|
||||
@NotNull(message = "单次限购数量不能为空")
|
||||
private Integer singleLimitCount;
|
||||
|
||||
@Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
|
||||
@NotNull(message = "活动时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
|
||||
@NotNull(message = "活动时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
|
||||
@NotNull(message = "开团人数不能为空")
|
||||
private Integer userSize;
|
||||
|
||||
@Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
@NotNull(message = "虚拟成团不能为空")
|
||||
private Boolean virtualGroup;
|
||||
|
||||
@Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@NotNull(message = "限制时长不能为空")
|
||||
private Integer limitDuration;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
|
||||
|
||||
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private List<CombinationProductBaseVO> products;
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团活动的分页项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationActivityPageItemRespVO extends CombinationActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<CombinationProductRespVO> 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;
|
||||
|
||||
// ========== 统计字段 ==========
|
||||
|
||||
@Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "33")
|
||||
private Integer groupCount;
|
||||
|
||||
@Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
|
||||
private Integer groupSuccessCount;
|
||||
|
||||
@Schema(description = "购买次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Integer recordCount;
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团活动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationActivityPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "拼团名称", example = "赵六")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "活动状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationActivityRespVO extends CombinationActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
|
||||
private Integer userSize;
|
||||
|
||||
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<CombinationProductRespVO> products;
|
||||
|
||||
@Schema(description = "商品 SPU 名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "一个白菜")
|
||||
private String spuName; // 从 SPU 的 name 读取
|
||||
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
|
||||
private String picUrl; // 从 SPU 的 picUrl 读取
|
||||
@Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
|
||||
private Integer marketPrice; // 从 SPU 的 marketPrice 读取
|
||||
|
||||
@Schema(description = "拼团金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
private Integer combinationPrice; // 从 products 获取最小 price 读取
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
|
||||
@NotNull(message = "活动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private List<CombinationProductBaseVO> products;
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 拼团商品 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class CombinationProductBaseVO {
|
||||
|
||||
@Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
|
||||
@NotNull(message = "商品 spuId 不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
|
||||
@NotNull(message = "商品 skuId 不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
|
||||
@NotNull(message = "拼团价格不能为空")
|
||||
private Integer combinationPrice;
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团商品分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationProductPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "拼团活动编号", example = "6829")
|
||||
private Long activityId;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", example = "18731")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", example = "31675")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "拼团商品状态", example = "2")
|
||||
private Integer activityStatus;
|
||||
|
||||
@Schema(description = "活动开始时间点")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] activityStartTime;
|
||||
|
||||
@Schema(description = "活动结束时间点")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] activityEndTime;
|
||||
|
||||
@Schema(description = "拼团价格,单位分", example = "27682")
|
||||
private Integer activePrice;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团商品 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationProductRespVO extends CombinationProductBaseVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 拼团记录 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CombinationRecordBaseVO {
|
||||
|
||||
@Schema(description = "拼团记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "拼团活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long activityId;
|
||||
|
||||
@Schema(description = "团长编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long headId;
|
||||
|
||||
// ========== 用户相关 ==========
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9430")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户昵称", example = "老芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
|
||||
private String avatar;
|
||||
|
||||
// ========== 商品相关 ==========
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23622")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29950")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "商品名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是大黄豆")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@Schema(description = "可参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
private Integer userSize;
|
||||
|
||||
@Schema(description = "已参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer userCount;
|
||||
|
||||
@Schema(description = "拼团状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
|
||||
private Boolean virtualGroup;
|
||||
|
||||
@Schema(description = "开始时间 (订单付款后开始的时间)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间(成团时间/失败时间)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团记录的分页项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationRecordPageItemRespVO extends CombinationRecordBaseVO {
|
||||
|
||||
// ========== 活动相关 ==========
|
||||
|
||||
private CombinationActivityRespVO activity;
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团记录分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationRecordReqPage2VO extends PageParam {
|
||||
|
||||
@Schema(description = "团长编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "团长编号不能为空")
|
||||
private Long headId;
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团记录分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CombinationRecordReqPageVO extends PageParam {
|
||||
|
||||
@Schema(description = "活动状态", example = "1")
|
||||
@InEnum(CombinationRecordStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "团长编号", example = "1024")
|
||||
private Long headId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.recrod;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 拼团记录信息统计 Response VO")
|
||||
@Data
|
||||
public class CombinationRecordSummaryVO {
|
||||
|
||||
@Schema(description = "所有拼团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long userCount;
|
||||
|
||||
@Schema(description = "成团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long successCount;
|
||||
|
||||
@Schema(description = "虚拟成团记录", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long virtualGroupCount;
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon;
|
||||
|
||||
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.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponSendReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 优惠劵")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/coupon")
|
||||
@Validated
|
||||
public class CouponController {
|
||||
|
||||
@Resource
|
||||
private CouponService couponService;
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "回收优惠劵")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon:delete')")
|
||||
public CommonResult<Boolean> deleteCoupon(@RequestParam("id") Long id) {
|
||||
couponService.deleteCoupon(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得优惠劵分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon:query')")
|
||||
public CommonResult<PageResult<CouponPageItemRespVO>> getCouponPage(@Valid CouponPageReqVO pageVO) {
|
||||
PageResult<CouponDO> pageResult = couponService.getCouponPage(pageVO);
|
||||
PageResult<CouponPageItemRespVO> pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult);
|
||||
if (CollUtil.isEmpty(pageResulVO.getList())) {
|
||||
return success(pageResulVO);
|
||||
}
|
||||
|
||||
// 读取用户信息,进行拼接
|
||||
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), CouponDO::getUserId));
|
||||
pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(),
|
||||
userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname())));
|
||||
return success(pageResulVO);
|
||||
}
|
||||
|
||||
@PostMapping("/send")
|
||||
@Operation(summary = "发送优惠劵")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon:send')")
|
||||
public CommonResult<Boolean> sendCoupon(@Valid @RequestBody CouponSendReqVO reqVO) {
|
||||
couponService.takeCouponByAdmin(reqVO.getTemplateId(), reqVO.getUserIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 优惠劵模板")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/coupon-template")
|
||||
@Validated
|
||||
public class CouponTemplateController {
|
||||
|
||||
@Resource
|
||||
private CouponTemplateService couponTemplateService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建优惠劵模板")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:create')")
|
||||
public CommonResult<Long> createCouponTemplate(@Valid @RequestBody CouponTemplateCreateReqVO createReqVO) {
|
||||
return success(couponTemplateService.createCouponTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新优惠劵模板")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')")
|
||||
public CommonResult<Boolean> updateCouponTemplate(@Valid @RequestBody CouponTemplateUpdateReqVO updateReqVO) {
|
||||
couponTemplateService.updateCouponTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(summary = "更新优惠劵模板状态")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')")
|
||||
public CommonResult<Boolean> updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) {
|
||||
couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除优惠劵模板")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:delete')")
|
||||
public CommonResult<Boolean> deleteCouponTemplate(@RequestParam("id") Long id) {
|
||||
couponTemplateService.deleteCouponTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得优惠劵模板")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')")
|
||||
public CommonResult<CouponTemplateRespVO> getCouponTemplate(@RequestParam("id") Long id) {
|
||||
CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(id);
|
||||
return success(CouponTemplateConvert.INSTANCE.convert(couponTemplate));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得优惠劵模板分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')")
|
||||
public CommonResult<PageResult<CouponTemplateRespVO>> getCouponTemplatePage(@Valid CouponTemplatePageReqVO pageVO) {
|
||||
PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(pageVO);
|
||||
return success(CouponTemplateConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得优惠劵模板列表")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')")
|
||||
public CommonResult<List<CouponTemplateRespVO>> getCouponTemplateList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<CouponTemplateDO> list = couponTemplateService.getCouponTemplateList(ids);
|
||||
return success(CouponTemplateConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class CouponBaseVO {
|
||||
|
||||
// ========== 基本信息 BEGIN ==========
|
||||
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "优惠劵模板编号不能为空")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
|
||||
@NotNull(message = "优惠劵名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "优惠码状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
// ========== 基本信息 END ==========
|
||||
|
||||
// ========== 领取情况 BEGIN ==========
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "领取方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "领取方式不能为空")
|
||||
private Integer takeType;
|
||||
// ========== 领取情况 END ==========
|
||||
|
||||
// ========== 使用规则 BEGIN ==========
|
||||
@Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 单位:分;0 - 不限制
|
||||
@NotNull(message = "是否设置满多少金额可用不能为空")
|
||||
private Integer usePrice;
|
||||
|
||||
@Schema(description = "固定日期 - 生效开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime validStartTime;
|
||||
|
||||
@Schema(description = "固定日期 - 生效结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime validEndTime;
|
||||
|
||||
@Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商品范围不能为空")
|
||||
@InEnum(PromotionProductScopeEnum.class)
|
||||
private Integer productScope;
|
||||
|
||||
@Schema(description = "商品范围编号的数组", example = "1,3")
|
||||
private List<Long> productScopeValues;
|
||||
// ========== 使用规则 END ==========
|
||||
|
||||
// ========== 使用效果 BEGIN ==========
|
||||
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "优惠类型不能为空")
|
||||
@InEnum(PromotionDiscountTypeEnum.class)
|
||||
private Integer discountType;
|
||||
|
||||
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
|
||||
private Integer discountPercent;
|
||||
|
||||
@Schema(description = "优惠金额", example = "10")
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
|
||||
private Integer discountLimitPrice;
|
||||
// ========== 使用效果 END ==========
|
||||
|
||||
// ========== 使用情况 BEGIN ==========
|
||||
|
||||
@Schema(description = "使用订单号", example = "4096")
|
||||
private Long useOrderId;
|
||||
|
||||
@Schema(description = "使用时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime useTime;
|
||||
|
||||
// ========== 使用情况 END ==========
|
||||
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵分页的每一项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponPageItemRespVO extends CouponRespVO {
|
||||
|
||||
@Schema(description = "用户昵称", example = "老芋艿")
|
||||
private String nickname;
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "优惠劵模板编号", example = "2048")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "优惠码状态", example = "1")
|
||||
@InEnum(value = CouponStatusEnum.class, message = "优惠劵状态,必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
@Schema(description = "用户昵称", example = "芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户编号", example = "1")
|
||||
private Collection<Long> userIds;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponRespVO extends CouponBaseVO {
|
||||
|
||||
@Schema(description = "优惠劵编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵发放 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class CouponSendReqVO {
|
||||
|
||||
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "优惠劵模板编号不能为空")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "用户编号列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
|
||||
@NotEmpty(message = "用户编号列表不能为空")
|
||||
private Set<Long> userIds;
|
||||
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class CouponTemplateBaseVO {
|
||||
|
||||
@Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
|
||||
@NotNull(message = "优惠劵名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "优惠券说明", example = "优惠券使用说明")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "发行总量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") // -1 - 则表示不限制发放数量
|
||||
@NotNull(message = "发行总量不能为空")
|
||||
private Integer totalCount;
|
||||
|
||||
@Schema(description = "每人限领个数", requiredMode = Schema.RequiredMode.REQUIRED, example = "66") // -1 - 则表示不限制
|
||||
@NotNull(message = "每人限领个数不能为空")
|
||||
private Integer takeLimitCount;
|
||||
|
||||
@Schema(description = "领取方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "领取方式不能为空")
|
||||
private Integer takeType;
|
||||
|
||||
@Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 单位:分;0 - 不限制
|
||||
@NotNull(message = "是否设置满多少金额可用不能为空")
|
||||
private Integer usePrice;
|
||||
|
||||
@Schema(description = "商品范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商品范围不能为空")
|
||||
@InEnum(PromotionProductScopeEnum.class)
|
||||
private Integer productScope;
|
||||
|
||||
@Schema(description = "商品范围编号的数组", example = "[1, 3]")
|
||||
private List<Long> productScopeValues;
|
||||
|
||||
@Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "生效日期类型不能为空")
|
||||
@InEnum(CouponTemplateValidityTypeEnum.class)
|
||||
private Integer validityType;
|
||||
|
||||
@Schema(description = "固定日期 - 生效开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime validStartTime;
|
||||
|
||||
@Schema(description = "固定日期 - 生效结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime validEndTime;
|
||||
|
||||
@Schema(description = "领取日期 - 开始天数")
|
||||
@Min(value = 0L, message = "开始天数必须大于 0")
|
||||
private Integer fixedStartTerm;
|
||||
|
||||
@Schema(description = "领取日期 - 结束天数")
|
||||
@Min(value = 1L, message = "开始天数必须大于 1")
|
||||
private Integer fixedEndTerm;
|
||||
|
||||
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "优惠类型不能为空")
|
||||
@InEnum(PromotionDiscountTypeEnum.class)
|
||||
private Integer discountType;
|
||||
|
||||
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
|
||||
private Integer discountPercent;
|
||||
|
||||
@Schema(description = "优惠金额", example = "10")
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
|
||||
private Integer discountLimitPrice;
|
||||
|
||||
@AssertTrue(message = "商品范围编号的数组不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isProductScopeValuesValid() {
|
||||
return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空
|
||||
|| CollUtil.isNotEmpty(productScopeValues);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "生效开始时间不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isValidStartTimeValid() {
|
||||
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType())
|
||||
|| validStartTime != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "生效结束时间不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isValidEndTimeValid() {
|
||||
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType())
|
||||
|| validEndTime != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "开始天数不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isFixedStartTermValid() {
|
||||
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType())
|
||||
|| fixedStartTerm != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "结束天数不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isFixedEndTermValid() {
|
||||
return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType())
|
||||
|| fixedEndTerm != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPercentValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "优惠金额不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPriceValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
|
||||
|| discountPrice != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "折扣上限不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountLimitPriceValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| discountLimitPrice != null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵模板创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponTemplateCreateReqVO extends CouponTemplateBaseVO {
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵模板分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponTemplatePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "优惠劵名", example = "你好")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "优惠类型", example = "1")
|
||||
private Integer discountType;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
@Schema(description = "可以领取的类型", example = "[1, 2, 3]")
|
||||
@InEnum(value = CouponTakeTypeEnum.class, message = "可以领取的类型,必须是 {value}")
|
||||
private List<Integer> canTakeTypes;
|
||||
|
||||
@Schema(description = "商品范围", example = "1")
|
||||
@InEnum(value = PromotionProductScopeEnum.class, message = "商品范围,必须是 {value}")
|
||||
private Integer productScope;
|
||||
|
||||
@Schema(description = "商品范围编号", example = "1")
|
||||
private Long productScopeValue;
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵模板 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponTemplateRespVO extends CouponTemplateBaseVO {
|
||||
|
||||
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "领取优惠券的数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Integer takeCount;
|
||||
|
||||
@Schema(description = "使用优惠券的次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||
private Integer useCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵模板更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO {
|
||||
|
||||
@Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "模板编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 优惠劵模板更新状态 Request VO")
|
||||
@Data
|
||||
public class CouponTemplateUpdateStatusReqVO {
|
||||
|
||||
@Schema(description = "优惠劵模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "优惠劵模板编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
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.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
|
||||
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.service.discount.DiscountActivityService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 限时折扣活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/discount-activity")
|
||||
@Validated
|
||||
public class DiscountActivityController {
|
||||
|
||||
@Resource
|
||||
private DiscountActivityService discountActivityService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建限时折扣活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')")
|
||||
public CommonResult<Long> createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) {
|
||||
return success(discountActivityService.createDiscountActivity(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新限时折扣活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')")
|
||||
public CommonResult<Boolean> updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) {
|
||||
discountActivityService.updateDiscountActivity(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@Operation(summary = "关闭限时折扣活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')")
|
||||
public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
|
||||
discountActivityService.closeDiscountActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除限时折扣活动")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')")
|
||||
public CommonResult<Boolean> deleteDiscountActivity(@RequestParam("id") Long id) {
|
||||
discountActivityService.deleteDiscountActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得限时折扣活动")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
|
||||
public CommonResult<DiscountActivityRespVO> getDiscountActivity(@RequestParam("id") Long id) {
|
||||
DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id);
|
||||
if (discountActivity == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接结果
|
||||
List<DiscountProductDO> discountProducts = discountActivityService.getDiscountProductsByActivityId(id);
|
||||
return success(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得限时折扣活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
|
||||
public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
|
||||
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(PageResult.empty(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 拼接数据
|
||||
List<DiscountProductDO> products = discountActivityService.getDiscountProductsByActivityId(
|
||||
convertSet(pageResult.getList(), DiscountActivityDO::getId));
|
||||
return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class DiscountActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "一个标题")
|
||||
@NotNull(message = "活动标题不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "开始时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "结束时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@Schema(description = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "商品")
|
||||
@Data
|
||||
public static class Product {
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "优惠类型不能为空")
|
||||
@InEnum(PromotionDiscountTypeEnum.class)
|
||||
private Integer discountType;
|
||||
|
||||
@Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
|
||||
private Integer discountPercent;
|
||||
|
||||
@Schema(description = "优惠金额", example = "10")
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@AssertTrue(message = "折扣百分比需要大于等于 0.01%,小于等于 99.99%")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPercentValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| (discountPercent != null && discountPercent >= 1 && discountPercent <= 9999);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "优惠金额不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPriceValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
|
||||
|| discountPrice != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 限时折扣活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO {
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
@NotEmpty(message = "商品列表不能为空")
|
||||
@Valid
|
||||
private List<Product> products;
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 限时折扣活动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "活动标题", example = "一个标题")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "活动状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 限时折扣活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityRespVO extends DiscountActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "活动状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<Product> products;
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 限时折扣活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO {
|
||||
|
||||
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "活动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
@NotEmpty(message = "商品列表不能为空")
|
||||
@Valid
|
||||
private List<Product> products;
|
||||
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.diy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.diy.vo.page.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.diy.DiyPageConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.diy.DiyPageDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.diy.DiyPageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 装修页面")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/diy-page")
|
||||
@Validated
|
||||
public class DiyPageController {
|
||||
|
||||
@Resource
|
||||
private DiyPageService diyPageService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建装修页面")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:create')")
|
||||
public CommonResult<Long> createDiyPage(@Valid @RequestBody DiyPageCreateReqVO createReqVO) {
|
||||
return success(diyPageService.createDiyPage(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新装修页面")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:update')")
|
||||
public CommonResult<Boolean> updateDiyPage(@Valid @RequestBody DiyPageUpdateReqVO updateReqVO) {
|
||||
diyPageService.updateDiyPage(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除装修页面")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:delete')")
|
||||
public CommonResult<Boolean> deleteDiyPage(@RequestParam("id") Long id) {
|
||||
diyPageService.deleteDiyPage(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得装修页面")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:query')")
|
||||
public CommonResult<DiyPageRespVO> getDiyPage(@RequestParam("id") Long id) {
|
||||
DiyPageDO diyPage = diyPageService.getDiyPage(id);
|
||||
return success(DiyPageConvert.INSTANCE.convert(diyPage));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得装修页面列表")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:query')")
|
||||
public CommonResult<List<DiyPageRespVO>> getDiyPageList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<DiyPageDO> list = diyPageService.getDiyPageList(ids);
|
||||
return success(DiyPageConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得装修页面分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:query')")
|
||||
public CommonResult<PageResult<DiyPageRespVO>> getDiyPagePage(@Valid DiyPagePageReqVO pageVO) {
|
||||
PageResult<DiyPageDO> pageResult = diyPageService.getDiyPagePage(pageVO);
|
||||
return success(DiyPageConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/get-property")
|
||||
@Operation(summary = "获得装修页面属性")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:query')")
|
||||
public CommonResult<DiyPagePropertyRespVO> getDiyPageProperty(@RequestParam("id") Long id) {
|
||||
DiyPageDO diyPage = diyPageService.getDiyPage(id);
|
||||
return success(DiyPageConvert.INSTANCE.convertPropertyVo(diyPage));
|
||||
}
|
||||
|
||||
@PutMapping("/update-property")
|
||||
@Operation(summary = "更新装修页面属性")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-page:update')")
|
||||
public CommonResult<Boolean> updateDiyPageProperty(@Valid @RequestBody DiyPagePropertyUpdateRequestVO updateReqVO) {
|
||||
diyPageService.updateDiyPageProperty(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.diy;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.diy.vo.template.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.diy.DiyTemplateConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.diy.DiyPageDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.diy.DiyTemplateDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.diy.DiyPageService;
|
||||
import cn.iocoder.yudao.module.promotion.service.diy.DiyTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 装修模板")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/diy-template")
|
||||
@Validated
|
||||
public class DiyTemplateController {
|
||||
|
||||
@Resource
|
||||
private DiyTemplateService diyTemplateService;
|
||||
@Resource
|
||||
private DiyPageService diyPageService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建装修模板")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:create')")
|
||||
public CommonResult<Long> createDiyTemplate(@Valid @RequestBody DiyTemplateCreateReqVO createReqVO) {
|
||||
return success(diyTemplateService.createDiyTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新装修模板")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:update')")
|
||||
public CommonResult<Boolean> updateDiyTemplate(@Valid @RequestBody DiyTemplateUpdateReqVO updateReqVO) {
|
||||
diyTemplateService.updateDiyTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/use")
|
||||
@Operation(summary = "使用装修模板")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:use')")
|
||||
public CommonResult<Boolean> useDiyTemplate(@RequestParam("id") Long id) {
|
||||
diyTemplateService.useDiyTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除装修模板")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:delete')")
|
||||
public CommonResult<Boolean> deleteDiyTemplate(@RequestParam("id") Long id) {
|
||||
diyTemplateService.deleteDiyTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得装修模板")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:query')")
|
||||
public CommonResult<DiyTemplateRespVO> getDiyTemplate(@RequestParam("id") Long id) {
|
||||
DiyTemplateDO diyTemplate = diyTemplateService.getDiyTemplate(id);
|
||||
return success(DiyTemplateConvert.INSTANCE.convert(diyTemplate));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得装修模板分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:query')")
|
||||
public CommonResult<PageResult<DiyTemplateRespVO>> getDiyTemplatePage(@Valid DiyTemplatePageReqVO pageVO) {
|
||||
PageResult<DiyTemplateDO> pageResult = diyTemplateService.getDiyTemplatePage(pageVO);
|
||||
return success(DiyTemplateConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
// TODO @疯狂:这个要不和 getDiyTemplate 合并,然后 DiyTemplateRespVO 里面直接把 DiyPagePropertyRespVO 也加上。减少 VO 好了,管理后台 get 多返回点数据,也问题不大的。目的,还是想尽可能降低大家的理解成本哈;
|
||||
@GetMapping("/get-property")
|
||||
@Operation(summary = "获得装修模板属性")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:query')")
|
||||
public CommonResult<DiyTemplatePropertyRespVO> getDiyTemplateProperty(@RequestParam("id") Long id) {
|
||||
DiyTemplateDO diyTemplate = diyTemplateService.getDiyTemplate(id);
|
||||
List<DiyPageDO> pages = diyPageService.getDiyPageByTemplateId(id);
|
||||
return success(DiyTemplateConvert.INSTANCE.convertPropertyVo(diyTemplate, pages));
|
||||
}
|
||||
|
||||
// TODO @疯狂:这个接口,要不和 useDiyTemplate 合并成一个,然后 VO 改成我们新的 VO 规范。不改的字段,就不传递。
|
||||
@PutMapping("/update-property")
|
||||
@Operation(summary = "更新装修模板属性")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:diy-template:update')")
|
||||
public CommonResult<Boolean> updateDiyTemplateProperty(@Valid @RequestBody DiyTemplatePropertyUpdateRequestVO updateReqVO) {
|
||||
diyTemplateService.updateDiyTemplateProperty(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.diy.vo.page;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装修页面 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class DiyPageBaseVO {
|
||||
|
||||
@Schema(description = "装修模板编号", example = "26179")
|
||||
private Long templateId;
|
||||
|
||||
@Schema(description = "页面名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
|
||||
@NotNull(message = "页面名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "备注", example = "随便")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "预览图")
|
||||
private List<String> previewPicUrls;
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user