mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-02-20 19:20:32 +08:00
mall + promotion:review 秒杀、评论代码
This commit is contained in:
parent
b16632ea41
commit
2efdbf93cb
@ -30,6 +30,7 @@ public interface ProductSkuApi {
|
||||
*/
|
||||
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
|
||||
|
||||
// TODO puhui999:入参用 Collection<Long> 更通用
|
||||
/**
|
||||
* 批量查询 SKU 数组
|
||||
*
|
||||
|
@ -28,7 +28,6 @@ public class ProductSpuApiImpl implements ProductSpuApi {
|
||||
|
||||
@Override
|
||||
public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
|
||||
// TODO 需不需要判断集合中是否有 null 值
|
||||
if (CollectionUtil.isEmpty(spuIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class ProductCommentBaseVO {
|
||||
@NotNull(message = "评价人头像不能为空")
|
||||
private String userAvatar;
|
||||
|
||||
// TODO @puhui:spuId、spuName 是不是只有 ProductCommentRespVO 有呀。
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
@ -54,7 +55,7 @@ public class ProductCommentBaseVO {
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
|
@ -35,6 +35,7 @@ public class ProductCommentPageReqVO extends PageParam {
|
||||
@InEnum(ProductCommentScoresEnum.class)
|
||||
private Integer scores;
|
||||
|
||||
// TODO @puhui999:replyStatus 哈
|
||||
@Schema(description = "商家是否回复", example = "true")
|
||||
private Boolean replied;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import lombok.ToString;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 商品评价可见修改 Request VO")
|
||||
@Schema(description = "管理后台 - 商品评价的商家回复 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class ProductCommentReplyReqVO {
|
||||
|
@ -56,19 +56,20 @@ public class AppProductCommentController {
|
||||
public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
|
||||
@RequestParam(value = "count", defaultValue = "10") Integer count) {
|
||||
return success(productCommentService.getCommentList(spuId, count));
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得商品评价分页")
|
||||
public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
|
||||
PageResult<AppProductCommentRespVO> page = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
|
||||
// TODO @puhui CollUtils 有简化 convertmap 和 list 的方法
|
||||
Set<Long> skuIds = page.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
|
||||
List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
|
||||
Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
|
||||
if (CollUtil.isNotEmpty(skuList)) {
|
||||
skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c)));
|
||||
}
|
||||
// TODO @puihui999:下面也可以放到 convert 里哈
|
||||
page.getList().forEach(item -> {
|
||||
// 判断用户是否选择匿名
|
||||
if (ObjectUtil.equal(item.getAnonymous(), true)) {
|
||||
@ -83,6 +84,7 @@ public class AppProductCommentController {
|
||||
return success(page);
|
||||
}
|
||||
|
||||
// TODO 芋艿:需要搞下
|
||||
@GetMapping("/getCommentStatistics")
|
||||
@Operation(summary = "获得商品的评价统计")
|
||||
public CommonResult<AppCommentStatisticsRespVO> getCommentStatistics(@Valid @RequestParam("spuId") Long spuId) {
|
||||
|
@ -1,56 +0,0 @@
|
||||
package cn.iocoder.yudao.module.product.controller.app.comment.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "用户 App - 商品评价创建 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class AppProductCommentCreateReqVO {
|
||||
|
||||
@Schema(description = "是否匿名", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@NotNull(message = "是否匿名不能为空")
|
||||
private Boolean anonymous;
|
||||
|
||||
@Schema(description = "交易订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2312312")
|
||||
@NotNull(message = "交易订单项编号不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖")
|
||||
@NotNull(message = "商品SPU名称不能为空")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192")
|
||||
@NotNull(message = "商品SKU编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "评分星级 1-5 分不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "描述星级 1-5 分不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
||||
@Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "服务星级 1-5 分不能为空")
|
||||
private Integer benefitScores;
|
||||
|
||||
@Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "哇,真的很丝滑凉快诶,好评")
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
}
|
@ -4,15 +4,12 @@ import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProdu
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 用户 App - 商品评价详情 Response VO
|
||||
*
|
||||
@ -54,7 +51,6 @@ public class AppProductCommentRespVO {
|
||||
private String replyContent;
|
||||
|
||||
@Schema(description = "商家回复时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime replyTime;
|
||||
|
||||
@Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶")
|
||||
@ -64,23 +60,21 @@ public class AppProductCommentRespVO {
|
||||
private List<String> additionalPicUrls;
|
||||
|
||||
@Schema(description = "追加评价时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime additionalTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "商品SPU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "91192")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品SPU名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖")
|
||||
@NotNull(message = "商品SPU名称不能为空")
|
||||
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑小短袖")
|
||||
@NotNull(message = "商品 SPU 名称不能为空")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品SKU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192")
|
||||
@NotNull(message = "商品SKU编号不能为空")
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "81192")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "商品 SKU 属性", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ -102,7 +96,7 @@ public class AppProductCommentRespVO {
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
|
@ -32,6 +32,7 @@ public interface ProductCommentConvert {
|
||||
|
||||
ProductCommentRespVO convert(ProductCommentDO bean);
|
||||
|
||||
// TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈
|
||||
@Mapping(target = "allCount", source = "allCount")
|
||||
@Mapping(target = "goodCount", source = "goodCount")
|
||||
@Mapping(target = "mediocreCount", source = "mediocreCount")
|
||||
|
@ -25,7 +25,6 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
|
||||
.orderByDesc(ProductCommentDO::getId));
|
||||
}
|
||||
|
||||
// TODO 芋艿:在看看这块
|
||||
static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
|
||||
// 构建好评查询语句:好评计算 总评 >= 4
|
||||
if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
|
||||
|
@ -149,13 +149,15 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
@Override
|
||||
public List<AppProductCommentRespVO> getCommentList(Long spuId, Integer count) {
|
||||
// 校验商品 spu 是否存在
|
||||
// TODO @puhui 这里校验可以去掉哈。
|
||||
ProductSpuDO spuDO = validateSpu(spuId);
|
||||
|
||||
return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuDO.getId(), count).getList());
|
||||
}
|
||||
|
||||
// TODO @puhui 可以放到 controller 去 convert 哈
|
||||
@Override
|
||||
public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
|
||||
// TODO @puhui 可以放到 controller 去 convert 哈
|
||||
return ProductCommentConvert.INSTANCE.convertPage02(
|
||||
productCommentMapper.selectPage(pageVO, visible));
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||
@Data
|
||||
public class SeckillActivityBaseVO {
|
||||
|
||||
// TODO @puhui999:对应单 spuId 哈
|
||||
@Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
|
||||
@NotNull(message = "秒杀活动商品不能为空")
|
||||
private List<Long> spuIds;
|
||||
@ -45,7 +46,7 @@ public class SeckillActivityBaseVO {
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "秒杀时段id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
|
||||
@Schema(description = "秒杀时段 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
|
||||
@NotNull(message = "秒杀时段不能为空")
|
||||
private List<Long> configIds;
|
||||
|
||||
@ -55,6 +56,7 @@ public class SeckillActivityBaseVO {
|
||||
@Schema(description = "单次限够数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "31683")
|
||||
private Integer singleLimitCount;
|
||||
|
||||
// TODO @puhui999:这个应该是计算出来的字段,只返回,create 和 update 不用哈
|
||||
@Schema(description = "秒杀总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer totalStock;
|
||||
|
||||
|
@ -9,11 +9,6 @@ import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀活动创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
@ -7,11 +7,6 @@ import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀活动的详细 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀活动的详细 Response VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
|
@ -28,5 +28,4 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO {
|
||||
@Schema(description = "活动状态 开启:0 禁用:1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer status;
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,13 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀活动更新 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -29,5 +20,4 @@ public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO {
|
||||
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<SeckillProductUpdateReqVO> products;
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 管理后台 秒杀时段创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀时段创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
// TODO @puhui:VO 上不写注释,已经有注解啦。
|
||||
/**
|
||||
* 管理后台 - 秒杀时段分页 Request VO
|
||||
*
|
||||
|
@ -4,17 +4,9 @@ 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;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀时段 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀时段 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -28,7 +20,6 @@ public class SeckillConfigRespVO extends SeckillConfigBaseVO {
|
||||
private Integer seckillActivityCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
@ -7,11 +7,6 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀时段配置精简信息 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀时段配置精简信息 Response VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
|
@ -7,11 +7,6 @@ import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀时段更新 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀时段更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
@ -7,11 +7,6 @@ import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 管理后台 - 修改时段配置状态 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 修改时段配置状态 Request VO")
|
||||
@Data
|
||||
public class SeckillConfigUpdateStatusReqVo {
|
||||
@ -20,7 +15,7 @@ public class SeckillConfigUpdateStatusReqVo {
|
||||
@NotNull(message = "时段配置编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
@ -14,6 +14,7 @@ import javax.validation.constraints.NotNull;
|
||||
@Data
|
||||
public class SeckillProductBaseVO {
|
||||
|
||||
// TODO @puhui:spuId 不用传递;因为一个秒杀活动只对应一个 SPU 哈;
|
||||
@Schema(description = "商品spu_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
|
||||
@NotNull(message = "商品spu_id不能为空")
|
||||
private Long spuId;
|
||||
|
@ -59,6 +59,7 @@ public class AppActivityController {
|
||||
}
|
||||
Map<Long, List<AppActivityRespVO>> map = new HashMap<>();
|
||||
map.put(109L, randomList);
|
||||
map.put(2L, randomList);
|
||||
return success(map);
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ public interface SeckillActivityConvert {
|
||||
&& ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice());
|
||||
//&& ObjectUtil.equals(productDO.getQuota(), productVO.getQuota())
|
||||
//&& ObjectUtil.equals(productDO.getLimitCount(), productVO.getLimitCount());
|
||||
|
||||
}
|
||||
|
||||
default List<SeckillProductDO> convertList(SeckillActivityDO seckillActivity, List<SeckillProductCreateReqVO> products) {
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@ -34,10 +35,14 @@ public class SeckillProductDO extends BaseDO {
|
||||
private Long id;
|
||||
/**
|
||||
* 秒杀活动 id
|
||||
*
|
||||
* 关联 {@link SeckillActivityDO#getId()}
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 秒杀时段 id
|
||||
*
|
||||
* 关联 {@link SeckillConfigDO#getId()}
|
||||
*/
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> configIds;
|
||||
@ -57,8 +62,10 @@ public class SeckillProductDO extends BaseDO {
|
||||
* 秒杀库存
|
||||
*/
|
||||
private Integer stock;
|
||||
|
||||
/**
|
||||
* 秒杀商品状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum 对应的类}
|
||||
*/
|
||||
private Integer activityStatus;
|
||||
|
@ -38,13 +38,14 @@ public class SeckillConfigDO extends BaseDO {
|
||||
* 结束时间点
|
||||
*/
|
||||
private String endTime;
|
||||
// TODO puhui999:应该是轮播图; private List<String> sliderPicUrls;
|
||||
/**
|
||||
* 秒杀主图
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 状态 开启:0 禁用:1
|
||||
* <p>
|
||||
* 状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum 对应的类}
|
||||
*/
|
||||
private Integer status;
|
||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
||||
*/
|
||||
@Mapper
|
||||
public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
|
||||
|
||||
default PageResult<SeckillActivityDO> selectPage(SeckillActivityPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
|
||||
.likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
|
||||
@ -30,4 +31,5 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
|
||||
return selectList(new LambdaQueryWrapperX<SeckillActivityDO>()
|
||||
.eqIfPresent(SeckillActivityDO::getStatus, status));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,22 +65,24 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts());
|
||||
|
||||
// 插入秒杀活动
|
||||
SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
|
||||
SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
|
||||
seckillActivityMapper.insert(seckillActivity);
|
||||
seckillActivityMapper.insert(activity);
|
||||
// 插入商品
|
||||
List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(seckillActivity, createReqVO.getProducts());
|
||||
seckillProductMapper.insertBatch(productDOs);
|
||||
return seckillActivity.getId();
|
||||
List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts());
|
||||
seckillProductMapper.insertBatch(product);
|
||||
return activity.getId();
|
||||
}
|
||||
|
||||
private <T extends SeckillProductBaseVO> void validateProductSkuExistence(List<Long> spuIds, List<T> products) {
|
||||
Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId);
|
||||
// 校验 spu 个数是否相等
|
||||
// TODO @puhui999:不用校验 SPU 哈,只校验 sku 对应的 spuId 是否一致;
|
||||
Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId);
|
||||
if (ObjectUtil.notEqual(spuIds.size(), convertedSpuIds.size())) {
|
||||
throw exception(SKU_NOT_EXISTS);
|
||||
}
|
||||
// 获取所选 spu下的所有 sku
|
||||
// TODO @puhui999:变量可以简单一点;skus
|
||||
List<ProductSkuRespDTO> skuRespDTOs = productSkuApi.getSkuListBySpuId(spuIds);
|
||||
// 校验 sku 个数是否一致
|
||||
Set<Long> skuIdsSet = CollectionUtils.convertSet(products, T::getSkuId);
|
||||
@ -153,6 +155,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
* @param updateReqVO 更新的请求VO
|
||||
*/
|
||||
private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) {
|
||||
// TODO puhui999:要不这里简单一点;删除原本的,插入新增的;不做的这么细致
|
||||
// TODO puhui999:后续完善
|
||||
//List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateReqVO.getId());
|
||||
//List<SeckillProductUpdateReqVO> products = updateReqVO.getProducts();
|
||||
|
@ -82,6 +82,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
private void validateSeckillConfigConflict(String startTime, String endTime) {
|
||||
LocalTime startTime1 = LocalTime.parse(startTime);
|
||||
LocalTime endTime1 = LocalTime.parse(endTime);
|
||||
// TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈;
|
||||
// 检查选择的时间是否相等
|
||||
if (startTime1.equals(endTime1)) {
|
||||
throw exception(SECKILL_TIME_EQUAL);
|
||||
@ -93,11 +94,13 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
// 查询出所有的时段配置
|
||||
List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
|
||||
// 过滤出重叠的时段 ids
|
||||
// TODO @puhui999:感觉 findOne 就可以了?
|
||||
Set<Long> ids = configDOs.stream().filter((config) -> {
|
||||
LocalTime startTime2 = LocalTime.parse(config.getStartTime());
|
||||
LocalTime endTime2 = LocalTime.parse(config.getEndTime());
|
||||
// 判断时间是否重叠
|
||||
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
|
||||
// todo @puhui999:LocalDateUtils 可以写个工具类?是否是有重叠的时间?感觉别的场景,可能也会有需要
|
||||
return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
|
||||
// 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
|
||||
|| startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
|
||||
@ -127,6 +130,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
if (seckillConfigMapper.selectBatchIds(configIds).size() != configIds.size()) {
|
||||
throw exception(SECKILL_TIME_NOT_EXISTS);
|
||||
}
|
||||
// TODO @puhui999:应该要校验个 status 哈;如果有禁用的,也不行
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,11 +138,13 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
||||
return seckillConfigMapper.selectPage(pageVO);
|
||||
}
|
||||
|
||||
// TODO @puhui999:写个查询状态的; 尽可能通用哈
|
||||
@Override
|
||||
public List<SeckillConfigDO> getListAllSimple() {
|
||||
return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
|
||||
}
|
||||
|
||||
// TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧;
|
||||
@Override
|
||||
public void updateSeckillConfigStatus(Long id, Integer status) {
|
||||
// 校验秒杀时段是否存在
|
||||
|
@ -29,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(SeckillConfigServiceImpl.class)
|
||||
@Disabled // TODO 芋艿:未来开启
|
||||
@Disabled // TODO 芋艿:未来开启;后续要 review 下
|
||||
public class SeckillConfigServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
|
@ -29,7 +29,6 @@ public class TradeOrderApiImpl implements TradeOrderApi {
|
||||
if (item == null) {
|
||||
throw exception(ORDER_ITEM_NOT_FOUND);
|
||||
}
|
||||
|
||||
return item.getOrderId();
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,7 @@ public class AppTradeOrderController {
|
||||
@PostMapping("/item/create-comment")
|
||||
@Operation(summary = "创建交易订单项的评价")
|
||||
public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
|
||||
// TODO @puhui999:这个逻辑,最好写到 service 哈;
|
||||
Long loginUserId = getLoginUserId();
|
||||
// 先通过订单项 ID 查询订单项是否存在
|
||||
TradeOrderItemDO orderItemDO = tradeOrderService.getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
|
||||
@ -151,6 +152,7 @@ public class AppTradeOrderController {
|
||||
if (orderDO == null) {
|
||||
throw exception(ORDER_NOT_FOUND);
|
||||
}
|
||||
// TODO @puhui999:要校验订单已完成,但是未评价;
|
||||
|
||||
ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
|
||||
return success(productCommentApi.createComment(productCommentCreateReqDTO));
|
||||
|
@ -19,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO {
|
||||
@NotNull(message = "交易订单项编号不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
// TODO @puhui999:貌似不用这个字段哈;
|
||||
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "评分星级 1-5 分不能为空")
|
||||
private Integer scores;
|
||||
@ -35,7 +36,7 @@ public class AppTradeOrderItemCommentCreateReqVO {
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user