fix:修复 mall review @puhui999
This commit is contained in:
parent
9cbd0fec1c
commit
e7d8643665
|
@ -4,6 +4,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
|
|||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 时间工具类,用于 {@link java.time.LocalDateTime}
|
||||
|
@ -50,7 +51,7 @@ public class LocalDateTimeUtils {
|
|||
* 判断当前时间是否在该时间范围内
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param endTime 结束时间
|
||||
* @return 是否
|
||||
*/
|
||||
public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
|
@ -60,4 +61,23 @@ public class LocalDateTimeUtils {
|
|||
return LocalDateTimeUtil.isIn(LocalDateTime.now(), startTime, endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查时间重叠 不包含日期
|
||||
*
|
||||
* @param startTime1 需要校验的开始时间
|
||||
* @param endTime1 需要校验的结束时间
|
||||
* @param startTime2 校验所需的开始时间
|
||||
* @param endTime2 校验所需的结束时间
|
||||
* @return 是否重叠
|
||||
*/
|
||||
public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
|
||||
// 判断时间是否重叠
|
||||
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
|
||||
return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
|
||||
// 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
|
||||
|| startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
|
||||
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
|
||||
|| startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public interface ErrorCodeConstants {
|
|||
|
||||
// ========== 商品 评价 1008007000 ==========
|
||||
ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
|
||||
ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
|
||||
ErrorCode ORDER_SKU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
|
||||
ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
|
||||
ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在");
|
||||
|
||||
|
|
|
@ -26,23 +26,10 @@ 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;
|
||||
|
||||
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotNull(message = "商品 SPU 名称不能为空")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "评分星级不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "描述星级不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
|
|
@ -35,9 +35,8 @@ public class ProductCommentPageReqVO extends PageParam {
|
|||
@InEnum(ProductCommentScoresEnum.class)
|
||||
private Integer scores;
|
||||
|
||||
// TODO @puhui999:replyStatus 哈
|
||||
@Schema(description = "商家是否回复", example = "true")
|
||||
private Boolean replied;
|
||||
private Boolean replyStatus;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
|
|
|
@ -5,6 +5,7 @@ import lombok.Data;
|
|||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 商品评价 Response VO")
|
||||
|
@ -40,4 +41,15 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
|
|||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
|
||||
@NotNull(message = "商品 SPU 名称不能为空")
|
||||
private String spuName;
|
||||
|
||||
}
|
||||
|
|
|
@ -30,11 +30,6 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 商品 SPU 相关接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Tag(name = "管理后台 - 商品 SPU")
|
||||
@RestController
|
||||
@RequestMapping("/product/spu")
|
||||
|
|
|
@ -9,11 +9,6 @@ import lombok.ToString;
|
|||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -8,12 +8,6 @@ import lombok.ToString;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 详细 Response VO
|
||||
* 包括关联的 SKU 等信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU 详细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -10,11 +10,6 @@ import java.time.LocalDateTime;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
|
|
|
@ -11,11 +11,6 @@ import java.time.LocalDateTime;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 商品 SPU 分页 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -7,11 +7,6 @@ import lombok.ToString;
|
|||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 商品 SPU Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 商品 SPU 精简 Response VO
|
||||
* TODO 商品 SPU 精简 VO 暂时没有使用到,用到的时候再按需添加\修改属性
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
|
|
|
@ -12,11 +12,6 @@ import javax.validation.Valid;
|
|||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 更新 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -7,11 +7,6 @@ import lombok.Data;
|
|||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 商品 SPU Status 更新 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO")
|
||||
@Data
|
||||
public class ProductSpuUpdateStatusReqVO{
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package cn.iocoder.yudao.module.product.controller.app.comment;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import com.google.common.collect.Maps;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
|
@ -26,11 +26,9 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
|
@ -61,26 +59,14 @@ public class AppProductCommentController {
|
|||
@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());
|
||||
PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
|
||||
Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
|
||||
List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
|
||||
Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
|
||||
Map<Long, ProductSkuDO> skuDOMap = Maps.newLinkedHashMapWithExpectedSize(skuIds.size());
|
||||
if (CollUtil.isNotEmpty(skuList)) {
|
||||
skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c)));
|
||||
skuDOMap.putAll(CollectionUtils.convertMap(skuList, ProductSkuDO::getId, c -> c));
|
||||
}
|
||||
// TODO @puihui999:下面也可以放到 convert 里哈
|
||||
page.getList().forEach(item -> {
|
||||
// 判断用户是否选择匿名
|
||||
if (ObjectUtil.equal(item.getAnonymous(), true)) {
|
||||
item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
|
||||
}
|
||||
ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
|
||||
if (productSkuDO != null) {
|
||||
List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
|
||||
item.setSkuProperties(skuProperties);
|
||||
}
|
||||
});
|
||||
PageResult<AppProductCommentRespVO> page = ProductCommentConvert.INSTANCE.convertPage02(commentDOPage, skuDOMap);
|
||||
return success(page);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,6 @@ import javax.validation.constraints.Size;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户 App - 商品评价详情 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "用户 App - 商品评价详情 Response VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cn.iocoder.yudao.module.product.convert.comment;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
|
@ -19,6 +20,7 @@ import org.mapstruct.factory.Mappers;
|
|||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品评价 Convert
|
||||
|
@ -32,10 +34,12 @@ public interface ProductCommentConvert {
|
|||
|
||||
ProductCommentRespVO convert(ProductCommentDO bean);
|
||||
|
||||
// TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈
|
||||
@Mapping(target = "goodCount", source = "goodCount")
|
||||
@Mapping(target = "mediocreCount", source = "mediocreCount")
|
||||
@Mapping(target = "negativeCount", source = "negativeCount")
|
||||
@Named("calculateOverallScore")
|
||||
default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
|
||||
return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
|
||||
}
|
||||
|
||||
@Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
|
||||
AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
|
||||
|
||||
List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
|
||||
|
@ -44,7 +48,23 @@ public interface ProductCommentConvert {
|
|||
|
||||
PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
|
||||
|
||||
PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
|
||||
PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
|
||||
|
||||
default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult, Map<Long, ProductSkuDO> skuDOMap) {
|
||||
PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
|
||||
page.getList().forEach(item -> {
|
||||
// 判断用户是否选择匿名
|
||||
if (ObjectUtil.equal(item.getAnonymous(), true)) {
|
||||
item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
|
||||
}
|
||||
ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
|
||||
if (productSkuDO != null) {
|
||||
List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
|
||||
item.setSkuProperties(skuProperties);
|
||||
}
|
||||
});
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算综合评分
|
||||
|
|
|
@ -51,11 +51,11 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
|
|||
return selectPage(reqVO, queryWrapper);
|
||||
}
|
||||
|
||||
default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long spuId) {
|
||||
default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long skuId) {
|
||||
return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
|
||||
.eq(ProductCommentDO::getUserId, userId)
|
||||
.eq(ProductCommentDO::getOrderItemId, orderItemId)
|
||||
.eq(ProductCommentDO::getSpuId, spuId));
|
||||
.eq(ProductCommentDO::getSpuId, skuId));
|
||||
}
|
||||
|
||||
default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) {
|
||||
|
|
|
@ -54,7 +54,7 @@ public interface ProductCommentService {
|
|||
* @param visible 是否可见
|
||||
* @return 商品评价分页
|
||||
*/
|
||||
PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
|
||||
PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
|
||||
|
||||
/**
|
||||
* 创建商品评论
|
||||
|
|
|
@ -81,7 +81,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createComment(ProductCommentCreateReqVO createReqVO) {
|
||||
// 校验评论
|
||||
validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
|
||||
validateComment(createReqVO.getSkuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
|
||||
|
||||
ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO);
|
||||
productCommentMapper.insert(commentDO);
|
||||
|
@ -108,11 +108,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
|||
return commentDO.getId();
|
||||
}
|
||||
|
||||
private void validateComment(Long spuId, Long userId, Long orderItemId) {
|
||||
private void validateComment(Long skuId, Long userId, Long orderItemId) {
|
||||
// 判断当前订单的当前商品用户是否评价过
|
||||
ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, spuId);
|
||||
ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
|
||||
if (null != exist) {
|
||||
throw exception(ORDER_SPU_COMMENT_EXISTS);
|
||||
throw exception(ORDER_SKU_COMMENT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,23 +141,17 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
|||
productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
|
||||
// 查询商品 id = spuId 的所有差评数量
|
||||
productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
|
||||
).setScores(3.0); // TODO @puhui999:这里要实现下;;
|
||||
);
|
||||
}
|
||||
|
||||
@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());
|
||||
return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuId, 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));
|
||||
public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
|
||||
return productCommentMapper.selectPage(pageVO, visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen
|
|||
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
|
||||
import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
|
||||
|
@ -128,7 +127,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
|||
productCommentPageReqVO.setSpuId(spuId);
|
||||
productCommentPageReqVO.setSpuName("感冒药");
|
||||
productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores());
|
||||
productCommentPageReqVO.setReplied(Boolean.TRUE);
|
||||
productCommentPageReqVO.setReplyStatus(Boolean.TRUE);
|
||||
|
||||
PageResult<ProductCommentDO> commentPage = productCommentService.getCommentPage(productCommentPageReqVO);
|
||||
PageResult<ProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO));
|
||||
|
@ -138,15 +137,15 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
|||
assertEquals(8, all.getTotal());
|
||||
|
||||
// 测试获取所有商品分页评论数据
|
||||
PageResult<AppProductCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
|
||||
PageResult<ProductCommentDO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
|
||||
assertEquals(7, result1.getTotal());
|
||||
|
||||
// 测试获取所有商品分页中评数据
|
||||
PageResult<AppProductCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
PageResult<ProductCommentDO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
assertEquals(2, result2.getTotal());
|
||||
|
||||
// 测试获取指定 spuId 商品分页中评数据
|
||||
PageResult<AppProductCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
PageResult<ProductCommentDO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
assertEquals(2, result3.getTotal());
|
||||
|
||||
// 测试分页 tab count
|
||||
|
|
|
@ -19,11 +19,6 @@ import java.util.List;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀时段相关接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Tag(name = "管理后台 - 秒杀时段")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/seckill-config")
|
||||
|
|
|
@ -9,11 +9,6 @@ import lombok.ToString;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀活动 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
|
@ -26,12 +30,24 @@ public class SeckillConfigBaseVO {
|
|||
@NotNull(message = "结束时间点不能为空")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "秒杀主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
|
||||
@NotNull(message = "秒杀主图不能为空")
|
||||
private String picUrl;
|
||||
@Schema(description = "秒杀轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
|
||||
@NotNull(message = "秒杀轮播图不能为空")
|
||||
private List<String> sliderPicUrls;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@AssertTrue(message = "秒杀时段开始时间和结束时间不能相等")
|
||||
@JsonIgnore
|
||||
public boolean isValidStartTimeValid() {
|
||||
return !LocalTime.parse(startTime).equals(LocalTime.parse(endTime));
|
||||
}
|
||||
|
||||
@AssertTrue(message = "秒杀时段开始时间不能在结束时间之后")
|
||||
@JsonIgnore
|
||||
public boolean isValidEndTimeValid() {
|
||||
return !LocalTime.parse(startTime).isAfter(LocalTime.parse(endTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,12 +6,6 @@ import lombok.Data;
|
|||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
// TODO @puhui:VO 上不写注释,已经有注解啦。
|
||||
/**
|
||||
* 管理后台 - 秒杀时段分页 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀时段分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀参与商品创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
@Schema(description = "管理后台 - 秒杀参与商品创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 管理后台 - 秒杀参与商品 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 秒杀参与商品 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3,22 +3,27 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig;
|
|||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀时段 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("promotion_seckill_config")
|
||||
@TableName(value = "promotion_seckill_config", autoResultMap = true)
|
||||
@KeySequence("promotion_seckill_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SeckillConfigDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
@ -38,14 +43,14 @@ public class SeckillConfigDO extends BaseDO {
|
|||
* 结束时间点
|
||||
*/
|
||||
private String endTime;
|
||||
// TODO puhui999:应该是轮播图; private List<String> sliderPicUrls;
|
||||
/**
|
||||
* 秒杀主图
|
||||
* 秒杀轮播图
|
||||
*/
|
||||
private String picUrl;
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<String> sliderPicUrls;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* <p>
|
||||
* 枚举 {@link CommonStatusEnum 对应的类}
|
||||
*/
|
||||
private Integer status;
|
||||
|
|
|
@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
|
|||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
|
||||
|
||||
|
@ -17,4 +19,9 @@ public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
|
|||
.orderByDesc(SeckillConfigDO::getId));
|
||||
}
|
||||
|
||||
default List<SeckillConfigDO> selectListByStatus(Integer status) {
|
||||
return selectList(SeckillConfigDO::getStatus, status);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
||||
|
@ -12,14 +13,13 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo
|
|||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
|
@ -37,9 +37,10 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|||
private SeckillConfigMapper seckillConfigMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
|
||||
// 校验时间段是否冲突
|
||||
validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime());
|
||||
validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null);
|
||||
|
||||
// 插入
|
||||
SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO);
|
||||
|
@ -49,18 +50,30 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateSeckillConfigExists(updateReqVO.getId());
|
||||
// 校验时间段是否冲突
|
||||
validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime());
|
||||
validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime(), updateReqVO.getId());
|
||||
|
||||
// 更新
|
||||
SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO);
|
||||
seckillConfigMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
// TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧; 更新状态不用那么多必须的参数,更新的时候需要校验时间段
|
||||
@Override
|
||||
public void updateSeckillConfigStatus(Long id, Integer status) {
|
||||
// 校验秒杀时段是否存在
|
||||
validateSeckillConfigExists(id);
|
||||
|
||||
// 更新状态
|
||||
seckillConfigMapper.updateById(new SeckillConfigDO().setId(id).setStatus(status));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteSeckillConfig(Long id) {
|
||||
// 校验存在
|
||||
validateSeckillConfigExists(id);
|
||||
|
@ -81,39 +94,29 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
*/
|
||||
private void validateSeckillConfigConflict(String startTime, String endTime) {
|
||||
private void validateSeckillConfigConflict(String startTime, String endTime, Long seckillConfigId) {
|
||||
LocalTime startTime1 = LocalTime.parse(startTime);
|
||||
LocalTime endTime1 = LocalTime.parse(endTime);
|
||||
// TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈;
|
||||
// 检查选择的时间是否相等
|
||||
if (startTime1.equals(endTime1)) {
|
||||
throw exception(SECKILL_TIME_EQUAL);
|
||||
}
|
||||
// 检查开始时间是否在结束时间之前
|
||||
if (startTime1.isAfter(endTime1)) {
|
||||
throw exception(SECKILL_START_TIME_BEFORE_END_TIME);
|
||||
}
|
||||
// 查询出所有的时段配置
|
||||
List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
|
||||
// 更新时排除自己
|
||||
if (seckillConfigId != null) {
|
||||
configDOs.removeIf(item -> ObjectUtil.equal(item.getId(), seckillConfigId));
|
||||
}
|
||||
// 过滤出重叠的时段 ids
|
||||
// TODO @puhui999:感觉 findOne 就可以了?
|
||||
Set<Long> ids = configDOs.stream().filter((config) -> {
|
||||
boolean hasConflict = configDOs.stream().anyMatch(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)
|
||||
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
|
||||
|| startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
|
||||
}).map(SeckillConfigDO::getId).collect(Collectors.toSet());
|
||||
if (CollUtil.isNotEmpty(ids)) {
|
||||
return LocalDateTimeUtils.checkTimeOverlap(startTime1, endTime1, startTime2, endTime2);
|
||||
});
|
||||
|
||||
if (hasConflict) {
|
||||
throw exception(SECKILL_TIME_CONFLICTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SeckillConfigDO getSeckillConfig(Long id) {
|
||||
return seckillConfigMapper.selectById(id);
|
||||
|
@ -148,23 +151,9 @@ 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) {
|
||||
// 校验秒杀时段是否存在
|
||||
validateSeckillConfigExists(id);
|
||||
|
||||
SeckillConfigDO seckillConfigDO = new SeckillConfigDO();
|
||||
seckillConfigDO.setId(id);
|
||||
seckillConfigDO.setStatus(status);
|
||||
// 更新状态
|
||||
seckillConfigMapper.updateById(seckillConfigDO);
|
||||
return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配");
|
||||
ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态");
|
||||
ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态");
|
||||
ErrorCode ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单不是【已完成】状态");
|
||||
ErrorCode ORDER_COMMENT_STATUS_NOT_FALSE = new ErrorCode(1011000019, "创建交易订单项的评价失败,订单已评价");
|
||||
|
||||
// ========== After Sale 模块 1011000100 ==========
|
||||
ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");
|
||||
|
|
|
@ -4,8 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
|
||||
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
|
||||
|
@ -30,13 +28,10 @@ import javax.validation.Valid;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
|
||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
|
||||
|
||||
@Tag(name = "用户 App - 交易订单")
|
||||
@RestController
|
||||
|
@ -47,12 +42,8 @@ public class AppTradeOrderController {
|
|||
|
||||
@Resource
|
||||
private TradeOrderService tradeOrderService;
|
||||
|
||||
@Resource
|
||||
private ProductPropertyValueApi productPropertyValueApi;
|
||||
@Resource
|
||||
private ProductCommentApi productCommentApi;
|
||||
|
||||
@Resource
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
|
||||
|
@ -121,7 +112,7 @@ public class AppTradeOrderController {
|
|||
// 待发货
|
||||
orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
|
||||
// 待收货
|
||||
orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null));
|
||||
orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null));
|
||||
// 待评价
|
||||
orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false));
|
||||
return success(orderCount);
|
||||
|
@ -164,22 +155,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);
|
||||
if (orderItemDO == null) {
|
||||
throw exception(ORDER_ITEM_NOT_FOUND);
|
||||
}
|
||||
// 校验订单
|
||||
TradeOrderDO orderDO = tradeOrderService.getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
|
||||
if (orderDO == null) {
|
||||
throw exception(ORDER_NOT_FOUND);
|
||||
}
|
||||
// TODO @puhui999:要校验订单已完成,但是未评价;
|
||||
|
||||
ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
|
||||
return success(productCommentApi.createComment(productCommentCreateReqDTO));
|
||||
return success(tradeOrderService.createOrderItemComment(createReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,11 +19,6 @@ 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;
|
||||
|
||||
@Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
|
||||
@NotNull(message = "描述星级 1-5 分不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
|
|
@ -270,7 +270,6 @@ public interface TradeOrderConvert {
|
|||
@Mapping(target = "skuId", source = "tradeOrderItemDO.skuId")
|
||||
@Mapping(target = "orderId", source = "tradeOrderItemDO.orderId")
|
||||
@Mapping(target = "orderItemId", source = "tradeOrderItemDO.id")
|
||||
@Mapping(target = "scores", source = "createReqVO.scores")
|
||||
@Mapping(target = "descriptionScores", source = "createReqVO.descriptionScores")
|
||||
@Mapping(target = "benefitScores", source = "createReqVO.benefitScores")
|
||||
@Mapping(target = "content", source = "createReqVO.content")
|
||||
|
|
|
@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreate
|
|||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||
|
||||
|
@ -177,4 +178,14 @@ public interface TradeOrderService {
|
|||
* @return 得到订单
|
||||
*/
|
||||
TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId);
|
||||
|
||||
/**
|
||||
* 创建订单项评论
|
||||
* 创建交易订单项的评价
|
||||
*
|
||||
* @param createReqVO 创建请求
|
||||
* @return 得到评价 id
|
||||
*/
|
||||
Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO);
|
||||
|
||||
}
|
||||
|
|
|
@ -17,19 +17,21 @@ import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
|
|||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
|
||||
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
|
||||
|
@ -57,6 +59,7 @@ import java.util.*;
|
|||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND;
|
||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||
|
||||
|
@ -93,7 +96,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
|||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
private ProductCommentApi productCommentApi;
|
||||
@Resource
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
|
||||
|
@ -556,6 +559,30 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
|||
return tradeOrderMapper.selectOrderByIdAndUserId(orderId, loginUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) {
|
||||
Long loginUserId = getLoginUserId();
|
||||
// 先通过订单项 ID 查询订单项是否存在
|
||||
TradeOrderItemDO orderItemDO = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
|
||||
if (orderItemDO == null) {
|
||||
throw exception(ORDER_ITEM_NOT_FOUND);
|
||||
}
|
||||
// 校验订单
|
||||
TradeOrderDO orderDO = getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
|
||||
if (orderDO == null) {
|
||||
throw exception(ORDER_NOT_FOUND);
|
||||
}
|
||||
if (ObjectUtil.notEqual(orderDO.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
|
||||
throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
|
||||
}
|
||||
if (ObjectUtil.notEqual(orderDO.getCommentStatus(), Boolean.FALSE)) {
|
||||
throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
|
||||
}
|
||||
|
||||
ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
|
||||
return productCommentApi.createComment(productCommentCreateReqDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定订单的所有订单项,是不是都售后成功
|
||||
*
|
||||
|
|
|
@ -19,10 +19,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* {@link AddressServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
* {@link AddressServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(AddressServiceImpl.class)
|
||||
public class AddressServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
|
@ -82,8 +82,8 @@ public class AddressServiceImplTest extends BaseDbUnitTest {
|
|||
|
||||
// 调用
|
||||
addressService.deleteAddress(dbAddress.getUserId(), id);
|
||||
// 校验数据不存在了
|
||||
assertNull(addressMapper.selectById(id));
|
||||
// 校验数据不存在了
|
||||
assertNull(addressMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue