mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
!499 完善商品管理 review 提到的问题
Merge pull request !499 from puhui999/feature/mall_product
This commit is contained in:
commit
0e817b190f
@ -23,7 +23,11 @@
|
||||
<artifactId>yudao-module-product-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-trade-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-member-api</artifactId>
|
||||
@ -35,11 +39,6 @@
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||
</dependency>
|
||||
<!-- TODO 芋艿:是不是可以去掉这个依赖呀? -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
|
@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreat
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
|
||||
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.service.comment.ProductCommentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -18,6 +17,7 @@ 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.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
@ -37,8 +37,13 @@ public class AppCommentController {
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得商品评价分页")
|
||||
public CommonResult<PageResult<AppCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
|
||||
PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
|
||||
return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult));
|
||||
return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
|
||||
}
|
||||
|
||||
@GetMapping("/get-count")
|
||||
@Operation(summary = "获得商品评价分页 tab count")
|
||||
public CommonResult<Map<String, Long>> getCommentPage(@Valid Long spuId) {
|
||||
return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
|
@ -14,8 +14,57 @@ import javax.validation.constraints.NotNull;
|
||||
@ToString(callSuper = true)
|
||||
public class AppCommentPageReqVO extends PageParam {
|
||||
|
||||
/**
|
||||
* 所有
|
||||
*/
|
||||
public static final Integer ALL = 0;
|
||||
|
||||
/**
|
||||
* 所有数量 key
|
||||
*/
|
||||
public static final String ALL_COUNT = "allCount";
|
||||
|
||||
/**
|
||||
* 好评
|
||||
*/
|
||||
public static final Integer FAVOURABLE_COMMENT = 1;
|
||||
|
||||
/**
|
||||
* 好评数量 key
|
||||
*/
|
||||
public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount";
|
||||
|
||||
/**
|
||||
* 中评
|
||||
*/
|
||||
public static final Integer MEDIOCRE_COMMENT = 2;
|
||||
|
||||
/**
|
||||
* 中评数量 key
|
||||
*/
|
||||
public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount";
|
||||
|
||||
/**
|
||||
* 差评
|
||||
*/
|
||||
public static final Integer NEGATIVE_COMMENT = 3;
|
||||
|
||||
/**
|
||||
* 差评数量 key
|
||||
*/
|
||||
public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount";
|
||||
|
||||
/**
|
||||
* 默认匿名昵称
|
||||
*/
|
||||
public static final String ANONYMOUS_NICKNAME = "匿名用户";
|
||||
|
||||
@Schema(description = "商品SPU编号", example = "29502")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "app 评论页 tab 类型 (0 全部、1 好评、2 中评、3 差评)", example = "0")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -27,7 +26,7 @@ public class AppCommentRespVO extends AppCommentBaseVO {
|
||||
@Schema(description = "订单项编号", required = true, example = "24965")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true)
|
||||
@Schema(description = "是否匿名", required = true)
|
||||
private Boolean anonymous;
|
||||
|
||||
@Schema(description = "交易订单编号", required = true, example = "24428")
|
||||
@ -36,7 +35,7 @@ public class AppCommentRespVO extends AppCommentBaseVO {
|
||||
@Schema(description = "交易订单项编号", required = true, example = "8233")
|
||||
private Long orderItemId;
|
||||
|
||||
@Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true)
|
||||
@Schema(description = "商家是否回复", required = true)
|
||||
private Boolean replied;
|
||||
|
||||
@Schema(description = "回复管理员编号", example = "22212")
|
||||
@ -60,4 +59,6 @@ public class AppCommentRespVO extends AppCommentBaseVO {
|
||||
@Schema(description = "创建时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "最终评分", required = true)
|
||||
private Integer finalScore;
|
||||
}
|
||||
|
@ -5,14 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -25,12 +19,8 @@ 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.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
||||
|
||||
@Tag(name = "用户 APP - 商品 SPU")
|
||||
@RestController
|
||||
@ -40,10 +30,6 @@ public class AppProductSpuController {
|
||||
|
||||
@Resource
|
||||
private ProductSpuService productSpuService;
|
||||
@Resource
|
||||
private ProductSkuService productSkuService;
|
||||
@Resource
|
||||
private ProductPropertyValueService productPropertyValueService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得商品 SPU 分页")
|
||||
@ -56,22 +42,7 @@ public class AppProductSpuController {
|
||||
@Operation(summary = "获得商品 SPU 明细")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
|
||||
// 获得商品 SPU
|
||||
ProductSpuDO spu = productSpuService.getSpu(id);
|
||||
if (spu == null) {
|
||||
throw exception(SPU_NOT_EXISTS);
|
||||
}
|
||||
if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
|
||||
throw exception(SPU_NOT_ENABLE);
|
||||
}
|
||||
|
||||
// 查询商品 SKU
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
||||
// 查询商品属性
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
||||
// 拼接
|
||||
return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues));
|
||||
return success(productSpuService.getAppProductSpuDetail(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@ -22,6 +21,15 @@ import lombok.*;
|
||||
@AllArgsConstructor
|
||||
public class ProductPropertyDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 默认属性id
|
||||
*/
|
||||
public static final Long PROPERTY_ID = 0L;
|
||||
/**
|
||||
* 默认属性名字
|
||||
*/
|
||||
public static final String PROPERTY_NAME = "默认";
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@ -23,6 +22,15 @@ import lombok.*;
|
||||
@AllArgsConstructor
|
||||
public class ProductPropertyValueDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 默认属性值id
|
||||
*/
|
||||
public static final Long VALUE_ID = 0L;
|
||||
/**
|
||||
* 默认属性值名字
|
||||
*/
|
||||
public static final String VALUE_NAME = "默认";
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.product.dal.mysql.comment;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
@ -34,11 +35,33 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
|
||||
.orderByDesc(ProductCommentDO::getId));
|
||||
}
|
||||
|
||||
static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
|
||||
// 构建好评查询语句
|
||||
if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) {
|
||||
// 好评计算 (商品评分星级+服务评分星级) >= 8
|
||||
queryWrapper.apply("(scores + benefit_scores) >= 8");
|
||||
}
|
||||
// 构建中评查询语句
|
||||
if (ObjectUtil.equal(type, AppCommentPageReqVO.MEDIOCRE_COMMENT)) {
|
||||
// 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8
|
||||
queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8");
|
||||
}
|
||||
// 构建差评查询语句
|
||||
if (ObjectUtil.equal(type, AppCommentPageReqVO.NEGATIVE_COMMENT)) {
|
||||
// 差评计算 (商品评分星级+服务评分星级) <= 4
|
||||
queryWrapper.apply("(scores + benefit_scores) <= 4");
|
||||
}
|
||||
}
|
||||
|
||||
default PageResult<ProductCommentDO> selectPage(AppCommentPageReqVO reqVO, Boolean visible) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ProductCommentDO>()
|
||||
LambdaQueryWrapperX<ProductCommentDO> queryWrapper = new LambdaQueryWrapperX<ProductCommentDO>()
|
||||
.eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId())
|
||||
.eqIfPresent(ProductCommentDO::getVisible, visible)
|
||||
.orderByDesc(ProductCommentDO::getId));
|
||||
.eqIfPresent(ProductCommentDO::getVisible, visible);
|
||||
// 构建评价查询语句
|
||||
appendTabQuery(queryWrapper, reqVO.getType());
|
||||
// 按评价时间排序最新的显示在前面
|
||||
queryWrapper.orderByDesc(ProductCommentDO::getCreateTime);
|
||||
return selectPage(reqVO, queryWrapper);
|
||||
}
|
||||
|
||||
default void updateCommentVisible(Long id, Boolean visible) {
|
||||
@ -74,4 +97,13 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
|
||||
update(null, lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
default Long selectTabCount(Long spuId, Boolean visible, Integer type) {
|
||||
LambdaQueryWrapperX<ProductCommentDO> queryWrapper = new LambdaQueryWrapperX<ProductCommentDO>()
|
||||
.eqIfPresent(ProductCommentDO::getSpuId, spuId)
|
||||
.eqIfPresent(ProductCommentDO::getVisible, visible);
|
||||
// 构建评价查询语句
|
||||
appendTabQuery(queryWrapper, type);
|
||||
return selectCount(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
package cn.iocoder.yudao.module.product.dal.mysql.sku;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@ -63,23 +60,4 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
|
||||
return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
|
||||
}
|
||||
|
||||
// TODO @puhui999:貌似 IN 不出来数据哈。直接全部查询出来,处理就好列;
|
||||
/**
|
||||
* 更新 sku 属性值时使用的分页查询
|
||||
*
|
||||
* @param pageParam 页面参数
|
||||
* @return {@link PageResult}<{@link ProductSkuDO}>
|
||||
*/
|
||||
default PageResult<ProductSkuDO> selectPage(PageParam pageParam) {
|
||||
return selectPage(pageParam, new LambdaQueryWrapper<ProductSkuDO>().isNotNull(ProductSkuDO::getProperties));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询 sku properties 不等于 null 的数量
|
||||
*
|
||||
* @return {@link Long}
|
||||
*/
|
||||
default Long selectCountByPropertyNotNull() {
|
||||
return selectCount(new LambdaQueryWrapper<ProductSkuDO>().isNotNull(ProductSkuDO::getProperties));
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,10 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
throw exception(CATEGORY_EXISTS_CHILDREN);
|
||||
}
|
||||
// 校验分类是否绑定了 SPU
|
||||
validateProductCategoryIsHaveBindSpu(id);
|
||||
Long count = productSpuService.getSpuCountByCategoryId(id);
|
||||
if (0 != count) {
|
||||
throw exception(CATEGORY_HAVE_BIND_SPU);
|
||||
}
|
||||
// 删除
|
||||
productCategoryMapper.deleteById(id);
|
||||
}
|
||||
@ -96,14 +99,6 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @puhui999:不用抽方法,因为不太会复用这个方法哈。
|
||||
private void validateProductCategoryIsHaveBindSpu(Long id) {
|
||||
Long count = productSpuService.getSpuCountByCategoryId(id);
|
||||
if (0 != count) {
|
||||
throw exception(CATEGORY_HAVE_BIND_SPU);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductCategoryDO getCategory(Long id) {
|
||||
return productCategoryMapper.selectById(id);
|
||||
|
@ -7,10 +7,13 @@ 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.AppCommentAdditionalReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品评论 Service 接口
|
||||
*
|
||||
@ -50,7 +53,7 @@ public interface ProductCommentService {
|
||||
* @param visible 是否可见
|
||||
* @return 商品评价分页
|
||||
*/
|
||||
PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
|
||||
PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
|
||||
|
||||
/**
|
||||
* 创建商品评论
|
||||
@ -68,4 +71,12 @@ public interface ProductCommentService {
|
||||
*/
|
||||
void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 评论页面标签数
|
||||
*
|
||||
* @param spuId spu id
|
||||
* @param visible 是否可见
|
||||
* @return 获得商品评价分页 tab count
|
||||
*/
|
||||
Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.service.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.controller.admin.comment.vo.ProductCommentPageReqVO;
|
||||
@ -7,17 +8,28 @@ 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.AppCommentAdditionalReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
|
||||
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.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
|
||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
|
||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
|
||||
|
||||
/**
|
||||
* 商品评论 Service 实现类
|
||||
@ -30,6 +42,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
|
||||
@Resource
|
||||
private ProductCommentMapper productCommentMapper;
|
||||
@Resource
|
||||
private TradeOrderApi tradeOrderApi;
|
||||
|
||||
@Resource
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
@Override
|
||||
public PageResult<ProductCommentDO> getCommentPage(ProductCommentPageReqVO pageReqVO) {
|
||||
@ -53,13 +70,48 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
|
||||
return productCommentMapper.selectPage(pageVO, visible);
|
||||
public Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible) {
|
||||
Map<String, Long> countMap = new HashMap<>(4);
|
||||
// 查询商品 id = spuId 的所有评论数量
|
||||
countMap.put(AppCommentPageReqVO.ALL_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL));
|
||||
// 查询商品 id = spuId 的所有好评数量
|
||||
countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT));
|
||||
// 查询商品 id = spuId 的所有中评数量
|
||||
countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT));
|
||||
// 查询商品 id = spuId 的所有差评数量
|
||||
countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT, productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT));
|
||||
return countMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
|
||||
PageResult<AppCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible));
|
||||
result.getList().forEach(item -> {
|
||||
// 判断用户是否选择匿名
|
||||
if (ObjectUtil.equal(item.getAnonymous(), true)) {
|
||||
item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME);
|
||||
}
|
||||
// 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2
|
||||
BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores());
|
||||
BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN);
|
||||
item.setFinalScore(divide.intValue());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createComment(ProductCommentDO productComment, Boolean system) {
|
||||
if (!system) {
|
||||
// TODO 判断订单是否存在 fix
|
||||
TradeOrderRespDTO order = tradeOrderApi.getOrder(productComment.getOrderId());
|
||||
if (null == order) {
|
||||
throw exception(ORDER_NOT_FOUND);
|
||||
}
|
||||
// TODO 判断 SPU 是否存在 fix
|
||||
ProductSpuDO spu = productSpuService.getSpu(productComment.getSpuId());
|
||||
if (null == spu) {
|
||||
throw exception(SPU_NOT_EXISTS);
|
||||
}
|
||||
// 判断当前订单的当前商品用户是否评价过
|
||||
ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId());
|
||||
if (null != exist) {
|
||||
|
@ -71,8 +71,8 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
||||
// 更新
|
||||
ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
|
||||
productPropertyMapper.updateById(updateObj);
|
||||
// TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
|
||||
productSkuService.updateSkuProperty(updateObj);
|
||||
// 更新 sku 相关属性
|
||||
productSkuService.updateSkuProperty(updateObj.getId(), updateObj.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,10 +73,8 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
|
||||
// 更新
|
||||
ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
|
||||
productPropertyValueMapper.updateById(updateObj);
|
||||
|
||||
// TODO 芋艿:更新时,需要看看 sku 表 fix
|
||||
// TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
|
||||
productSkuService.updateSkuPropertyValue(updateObj);
|
||||
// 更新 sku 相关属性
|
||||
productSkuService.updateSkuPropertyValue(updateObj.getId(), updateObj.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.product.service.sku;
|
||||
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -111,16 +109,18 @@ public interface ProductSkuService {
|
||||
/**
|
||||
* 更新 sku 属性
|
||||
*
|
||||
* @param updateObj 属性对象
|
||||
* @param propertyId 属性 id
|
||||
* @param propertyName 属性名
|
||||
* @return int 影响的行数
|
||||
*/
|
||||
int updateSkuProperty(ProductPropertyDO updateObj);
|
||||
int updateSkuProperty(Long propertyId, String propertyName);
|
||||
|
||||
/**
|
||||
* 更新 sku 属性值
|
||||
*
|
||||
* @param updateObj 属性值对象
|
||||
* @param propertyValueId 属性值 id
|
||||
* @param propertyValueName 属性值名字
|
||||
* @return int 影响的行数
|
||||
*/
|
||||
int updateSkuPropertyValue(ProductPropertyValueDO updateObj);
|
||||
int updateSkuPropertyValue(Long propertyValueId, String propertyValueName);
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ package cn.iocoder.yudao.module.product.service.sku;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
@ -80,16 +79,25 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
|
||||
@Override
|
||||
public void validateSkuList(List<ProductSkuCreateOrUpdateReqVO> skus, Boolean specType) {
|
||||
// 非多规格,不需要校验
|
||||
if (ObjectUtil.notEqual(specType, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 0、校验skus是否为空
|
||||
if (CollUtil.isEmpty(skus)) {
|
||||
throw exception(SKU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 单规格处理
|
||||
if (ObjectUtil.equal(specType, false)) {
|
||||
ProductSkuCreateOrUpdateReqVO skuVO = skus.get(0);
|
||||
// 赋予单规格默认属性
|
||||
List<ProductSkuBaseVO.Property> properties = new ArrayList<>();
|
||||
ProductSkuBaseVO.Property property = new ProductSkuBaseVO.Property();
|
||||
property.setPropertyId(ProductPropertyDO.PROPERTY_ID);
|
||||
property.setPropertyName(ProductPropertyDO.PROPERTY_NAME);
|
||||
property.setValueId(ProductPropertyValueDO.VALUE_ID);
|
||||
property.setValueName(ProductPropertyValueDO.VALUE_NAME);
|
||||
properties.add(property);
|
||||
skuVO.setProperties(properties);
|
||||
// 单规格不需要后续的校验
|
||||
return;
|
||||
}
|
||||
// 1、校验属性项存在
|
||||
Set<Long> propertyIds = skus.stream().filter(p -> p.getProperties() != null)
|
||||
// 遍历多个 Property 属性
|
||||
@ -156,81 +164,51 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateSkuProperty(ProductPropertyDO updateObj) {
|
||||
// TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
|
||||
// TODO @puhui999:直接全部查询处理,批量处理就好列;一般项目的商品不会超过几十万的哈。
|
||||
Long count = productSkuMapper.selectCountByPropertyNotNull();
|
||||
int currentPage = 1;
|
||||
public int updateSkuProperty(Long propertyId, String propertyName) {
|
||||
// 获取所有的 sku
|
||||
List<ProductSkuDO> skuDOList = productSkuMapper.selectList();
|
||||
// 处理后需要更新的 sku
|
||||
List<ProductSkuDO> updateSkus = new ArrayList<>();
|
||||
if (count == 0) {
|
||||
if (CollUtil.isEmpty(skuDOList)) {
|
||||
return 0;
|
||||
}
|
||||
int pageSize = 100;
|
||||
for (int i = 0; i <= count / 100; i++) {
|
||||
PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize);
|
||||
// 分页查找出 sku 属性不为 null 的
|
||||
PageResult<ProductSkuDO> skuPage = productSkuMapper.selectPage(pageParam);
|
||||
List<ProductSkuDO> records = skuPage.getList();
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
break;
|
||||
}
|
||||
records.stream().filter(sku -> sku.getProperties() != null)
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getPropertyId().equals(updateObj.getId())) {
|
||||
property.setPropertyName(updateObj.getName());
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
}
|
||||
skuDOList.stream().filter(sku -> sku.getProperties() != null)
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getPropertyId().equals(propertyId)) {
|
||||
property.setPropertyName(propertyName);
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
if (CollUtil.isEmpty(updateSkus)) {
|
||||
return 0;
|
||||
}
|
||||
// TODO @puhui999:貌似 updateBatch 自己会拆分批次,这里不用再拆分了
|
||||
// 每批处理的大小
|
||||
int batchSize = 1000;
|
||||
for (int i = 0; i < updateSkus.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
|
||||
productSkuMapper.updateBatch(batchSkuDOs, batchSize);
|
||||
}
|
||||
|
||||
productSkuMapper.updateBatch(updateSkus);
|
||||
return updateSkus.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateSkuPropertyValue(ProductPropertyValueDO updateObj) {
|
||||
// TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
|
||||
Long count = productSkuMapper.selectCountByPropertyNotNull();
|
||||
int currentPage = 1;
|
||||
public int updateSkuPropertyValue(Long propertyValueId, String propertyValueName) {
|
||||
// 获取所有的 sku
|
||||
List<ProductSkuDO> skuDOList = productSkuMapper.selectList();
|
||||
// 处理后需要更新的 sku
|
||||
List<ProductSkuDO> updateSkus = new ArrayList<>();
|
||||
if (count == 0) {
|
||||
if (CollUtil.isEmpty(skuDOList)) {
|
||||
return 0;
|
||||
}
|
||||
int pageSize = 100;
|
||||
for (int i = 0; i <= count / 100; i++) {
|
||||
PageParam pageParam = new PageParam().setPageNo(currentPage + i).setPageSize(pageSize);
|
||||
// 分页查找出 sku 属性不为 null 的
|
||||
PageResult<ProductSkuDO> skuPage = productSkuMapper.selectPage(pageParam);
|
||||
List<ProductSkuDO> records = skuPage.getList();
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
break;
|
||||
}
|
||||
records.stream()
|
||||
.filter(sku -> sku.getProperties() != null)
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getValueId().equals(updateObj.getId())) {
|
||||
property.setValueName(updateObj.getName());
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
}
|
||||
skuDOList.stream()
|
||||
.filter(sku -> sku.getProperties() != null)
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getValueId().equals(propertyValueId)) {
|
||||
property.setValueName(propertyValueName);
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
if (CollUtil.isEmpty(updateSkus)) {
|
||||
return 0;
|
||||
}
|
||||
// 每批处理的大小
|
||||
int batchSize = 1000;
|
||||
for (int i = 0; i < updateSkus.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
|
||||
productSkuMapper.updateBatch(batchSkuDOs, batchSize);
|
||||
}
|
||||
|
||||
productSkuMapper.updateBatch(updateSkus);
|
||||
return updateSkus.size();
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.service.spu;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
|
||||
@ -135,4 +136,11 @@ public interface ProductSpuService {
|
||||
*/
|
||||
Long getSpuCountByCategoryId(Long id);
|
||||
|
||||
/**
|
||||
* 通过 spu id 获取商品 SPU 明细
|
||||
*
|
||||
* @param id id
|
||||
* @return 用户 App - 商品 SPU 明细
|
||||
*/
|
||||
AppProductSpuDetailRespVO getAppProductSpuDetail(Long id);
|
||||
}
|
||||
|
@ -7,15 +7,21 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -50,6 +56,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
private ProductBrandService brandService;
|
||||
@Resource
|
||||
private ProductCategoryService categoryService;
|
||||
@Resource
|
||||
@Lazy // 循环依赖,避免报错
|
||||
private ProductPropertyValueService productPropertyValueService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@ -140,7 +149,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
// 校验存在
|
||||
validateSpuExists(id);
|
||||
// 校验商品状态不是回收站不能删除
|
||||
validateSpuStatus(id);
|
||||
ProductSpuDO spuDO = productSpuMapper.selectById(id);
|
||||
// 判断 SPU 状态是否为回收站
|
||||
if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) {
|
||||
throw exception(SPU_NOT_RECYCLE);
|
||||
}
|
||||
|
||||
// 删除 SPU
|
||||
productSpuMapper.deleteById(id);
|
||||
@ -154,20 +167,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 SPU 状态是否为回收站
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
// TODO puhui999:感觉不用独立出来一个方法,直接在 deleteSpu 方法中校验即可
|
||||
private void validateSpuStatus(Long id) {
|
||||
ProductSpuDO spuDO = productSpuMapper.selectById(id);
|
||||
// 判断 SPU 状态是否为回收站
|
||||
if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) {
|
||||
throw exception(SPU_NOT_RECYCLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductSpuDO getSpu(Long id) {
|
||||
return productSpuMapper.selectById(id);
|
||||
@ -257,4 +256,35 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
return productSpuMapper.selectCount(ProductSpuDO::getCategoryId, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppProductSpuDetailRespVO getAppProductSpuDetail(Long id) {
|
||||
// 获得商品 SPU
|
||||
ProductSpuDO spu = getSpu(id);
|
||||
if (spu == null) {
|
||||
throw exception(SPU_NOT_EXISTS);
|
||||
}
|
||||
if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
|
||||
throw exception(SPU_NOT_ENABLE);
|
||||
}
|
||||
|
||||
// 查询商品 SKU
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues = new ArrayList<>();
|
||||
// 单规格商品 赋予默认属性值
|
||||
if (ObjectUtil.equal(spu.getSpecType(), false)) {
|
||||
ProductPropertyValueDetailRespBO respBO = new ProductPropertyValueDetailRespBO();
|
||||
respBO.setPropertyId(ProductPropertyDO.PROPERTY_ID);
|
||||
respBO.setPropertyName(ProductPropertyDO.PROPERTY_NAME);
|
||||
respBO.setValueId(ProductPropertyValueDO.VALUE_ID);
|
||||
respBO.setValueName(ProductPropertyValueDO.VALUE_NAME);
|
||||
propertyValues.add(respBO);
|
||||
} else {
|
||||
// 多规格商品则查询商品属性
|
||||
propertyValues = productPropertyValueService
|
||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
||||
}
|
||||
// 拼接
|
||||
return ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,15 +11,22 @@ 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.AppCommentAdditionalReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum;
|
||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
@ -39,8 +46,14 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
||||
private ProductCommentMapper productCommentMapper;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private ProductCommentServiceImpl productCommentService;
|
||||
|
||||
@MockBean
|
||||
private TradeOrderApi tradeOrderApi;
|
||||
@MockBean
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
public String generateNo() {
|
||||
return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999);
|
||||
}
|
||||
@ -70,6 +83,23 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
||||
o.setScores(ProductCommentScoresEnum.FOUR.getScores());
|
||||
o.setReplied(Boolean.TRUE);
|
||||
o.setVisible(Boolean.TRUE);
|
||||
o.setId(generateId());
|
||||
o.setUserId(generateId());
|
||||
o.setAnonymous(Boolean.TRUE);
|
||||
o.setOrderId(generateId());
|
||||
o.setOrderItemId(generateId());
|
||||
o.setSpuId(generateId());
|
||||
o.setSkuId(generateId());
|
||||
o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores());
|
||||
o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores());
|
||||
o.setDeliveryScores(ProductCommentScoresEnum.FOUR.getScores());
|
||||
o.setContent("真好吃");
|
||||
o.setReplyUserId(generateId());
|
||||
o.setReplyContent("确实");
|
||||
o.setReplyTime(LocalDateTime.now());
|
||||
o.setAdditionalTime(LocalDateTime.now());
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
o.setUpdateTime(LocalDateTime.now());
|
||||
});
|
||||
productCommentMapper.insert(productComment);
|
||||
|
||||
@ -77,7 +107,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
||||
Long spuId = productComment.getSpuId();
|
||||
|
||||
// 测试 userNickname 不匹配
|
||||
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三")));
|
||||
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三").setScores(ProductCommentScoresEnum.ONE.getScores())));
|
||||
// 测试 orderId 不匹配
|
||||
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setOrderId(generateId())));
|
||||
// 测试 spuId 不匹配
|
||||
@ -107,8 +137,25 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
|
||||
PageResult<ProductCommentDO> all = productCommentService.getCommentPage(new ProductCommentPageReqVO());
|
||||
assertEquals(8, all.getTotal());
|
||||
|
||||
PageResult<ProductCommentDO> visible = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
|
||||
assertEquals(7, visible.getTotal());
|
||||
// 测试获取所有商品分页评论数据
|
||||
PageResult<AppCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
|
||||
assertEquals(7, result1.getTotal());
|
||||
|
||||
// 测试获取所有商品分页中评数据
|
||||
PageResult<AppCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
assertEquals(2, result2.getTotal());
|
||||
|
||||
// 测试获取指定 spuId 商品分页中评数据
|
||||
PageResult<AppCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
|
||||
assertEquals(2, result3.getTotal());
|
||||
|
||||
// 测试分页 tab count
|
||||
Map<String, Long> tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE);
|
||||
assertEquals(6, tabsCount.get(AppCommentPageReqVO.ALL_COUNT));
|
||||
assertEquals(4, tabsCount.get(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT));
|
||||
assertEquals(2, tabsCount.get(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT));
|
||||
assertEquals(0, tabsCount.get(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.module.trade.api.order;
|
||||
|
||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
||||
|
||||
/**
|
||||
* 订单 API 接口
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface TradeOrderApi {
|
||||
|
||||
/**
|
||||
* 获取订单通过订单 id
|
||||
*
|
||||
* @param id id
|
||||
* @return 订单信息 Response DTO
|
||||
*/
|
||||
TradeOrderRespDTO getOrder(Long id);
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package cn.iocoder.yudao.module.trade.api.order.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 订单信息 Response DTO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class TradeOrderRespDTO {
|
||||
|
||||
// ========== 订单基本信息 ==========
|
||||
/**
|
||||
* 订单编号,主键自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 订单流水号
|
||||
* <p>
|
||||
* 例如说,1146347329394184195
|
||||
*/
|
||||
private String no;
|
||||
/**
|
||||
* 订单类型
|
||||
* <p>
|
||||
* 枚举 {@link TradeOrderTypeEnum}
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 订单来源
|
||||
* <p>
|
||||
* 枚举 {@link TerminalEnum}
|
||||
*/
|
||||
private Integer terminal;
|
||||
/**
|
||||
* 用户编号
|
||||
* <p>
|
||||
* 关联 MemberUserDO 的 id 编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
private String userIp;
|
||||
/**
|
||||
* 用户备注
|
||||
*/
|
||||
private String userRemark;
|
||||
/**
|
||||
* 订单状态
|
||||
* <p>
|
||||
* 枚举 {@link TradeOrderStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 购买的商品数量
|
||||
*/
|
||||
private Integer productCount;
|
||||
/**
|
||||
* 订单完成时间
|
||||
*/
|
||||
private LocalDateTime finishTime;
|
||||
/**
|
||||
* 订单取消时间
|
||||
*/
|
||||
private LocalDateTime cancelTime;
|
||||
/**
|
||||
* 取消类型
|
||||
* <p>
|
||||
* 枚举 {@link TradeOrderCancelTypeEnum}
|
||||
*/
|
||||
private Integer cancelType;
|
||||
/**
|
||||
* 商家备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 是否评价
|
||||
* <p>
|
||||
* true - 已评价
|
||||
* false - 未评价
|
||||
*/
|
||||
private Boolean commentStatus;
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.module.trade.api;
|
@ -23,7 +23,6 @@
|
||||
<artifactId>yudao-module-trade-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-product-api</artifactId>
|
||||
@ -44,6 +43,11 @@
|
||||
<artifactId>yudao-module-member-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-system-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.module.trade.api.order;
|
||||
|
||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
|
||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 订单 API 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class TradeOrderApiImpl implements TradeOrderApi {
|
||||
|
||||
@Resource
|
||||
private TradeOrderService tradeOrderService;
|
||||
|
||||
@Override
|
||||
public TradeOrderRespDTO getOrder(Long id) {
|
||||
return TradeOrderConvert.INSTANCE.convert(tradeOrderService.getOrder(id));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.module.trade.api;
|
@ -70,14 +70,14 @@ public class DeliveryExpressTemplateController {
|
||||
return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
// TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈
|
||||
// TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈 fix
|
||||
@GetMapping("/list-all-simple")
|
||||
@Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项")
|
||||
public CommonResult<List<DeliveryExpressTemplateRespVO>> getSimpleTemplateList() {
|
||||
public CommonResult<List<DeliveryExpressTemplateSimpleRespVO>> getSimpleTemplateList() {
|
||||
// 获取运费模版列表,只要开启状态的
|
||||
List<DeliveryExpressTemplateDO> list = deliveryExpressTemplateService.getDeliveryExpressTemplateList();
|
||||
// 排序后,返回给前端
|
||||
return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list));
|
||||
return success(DeliveryExpressTemplateConvert.INSTANCE.convertList1(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 模版精简信息 Response VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeliveryExpressTemplateSimpleRespVO {
|
||||
|
||||
@Schema(description = "模版编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "模板名称", required = true, example = "测试模版")
|
||||
private String name;
|
||||
|
||||
}
|
@ -28,11 +28,13 @@ public interface DeliveryExpressTemplateConvert {
|
||||
|
||||
List<DeliveryExpressTemplateRespVO> convertList(List<DeliveryExpressTemplateDO> list);
|
||||
|
||||
List<DeliveryExpressTemplateSimpleRespVO> convertList1(List<DeliveryExpressTemplateDO> list);
|
||||
|
||||
PageResult<DeliveryExpressTemplateRespVO> convertPage(PageResult<DeliveryExpressTemplateDO> page);
|
||||
|
||||
default DeliveryExpressTemplateDetailRespVO convert(DeliveryExpressTemplateDO bean,
|
||||
List<DeliveryExpressTemplateChargeDO> chargeList,
|
||||
List<DeliveryExpressTemplateFreeDO> freeList){
|
||||
List<DeliveryExpressTemplateFreeDO> freeList) {
|
||||
DeliveryExpressTemplateDetailRespVO respVO = convert2(bean);
|
||||
respVO.setTemplateCharge(convertTemplateChargeList(chargeList));
|
||||
respVO.setTemplateFree(convertTemplateFreeList(freeList));
|
||||
|
@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
|
||||
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
|
||||
@ -62,6 +63,8 @@ public interface TradeOrderConvert {
|
||||
TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO,
|
||||
TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address);
|
||||
|
||||
TradeOrderRespDTO convert(TradeOrderDO orderDO);
|
||||
|
||||
default List<TradeOrderItemDO> convertList(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) {
|
||||
return CollectionUtils.convertList(calculateRespBO.getItems(), item -> {
|
||||
TradeOrderItemDO orderItem = convert(item);
|
||||
|
@ -6,7 +6,9 @@ import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.module.member.api.address.AddressApi;
|
||||
@ -21,6 +23,11 @@ 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.notify.dto.NotifyTemplateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.enums.notify.NotifyTemplateTypeEnum;
|
||||
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;
|
||||
@ -29,6 +36,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle
|
||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
|
||||
@ -38,6 +46,7 @@ import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.*;
|
||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||
import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
|
||||
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
|
||||
import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
|
||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||
@ -74,6 +83,8 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
private TradeCartService tradeCartService;
|
||||
@Resource
|
||||
private TradePriceService tradePriceService;
|
||||
@Resource
|
||||
private DeliveryExpressService deliveryExpressService;
|
||||
|
||||
@Resource
|
||||
private ProductSkuApi productSkuApi;
|
||||
@ -85,7 +96,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
private CouponApi couponApi;
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
@Resource
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
|
||||
@ -123,7 +137,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
/**
|
||||
* 计算订单价格
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userId 用户编号
|
||||
* @param settlementReqVO 结算信息
|
||||
* @return 订单价格
|
||||
*/
|
||||
@ -162,7 +176,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
/**
|
||||
* 校验收件地址是否存在
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userId 用户编号
|
||||
* @param addressId 收件地址编号
|
||||
* @return 收件地址
|
||||
*/
|
||||
@ -181,7 +195,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
|
||||
order.setType(TradeOrderTypeEnum.NORMAL.getType());
|
||||
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
|
||||
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
||||
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
||||
order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源?
|
||||
// 支付信息
|
||||
order.setAdjustPrice(0).setPayed(false);
|
||||
@ -201,12 +215,12 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
/**
|
||||
* 执行创建完创建完订单后的逻辑
|
||||
*
|
||||
* <p>
|
||||
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param createReqVO 创建订单请求
|
||||
* @param tradeOrderDO 交易订单
|
||||
* @param userId 用户编号
|
||||
* @param createReqVO 创建订单请求
|
||||
* @param tradeOrderDO 交易订单
|
||||
* @param calculateRespBO 订单价格计算结果
|
||||
*/
|
||||
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
||||
@ -265,11 +279,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
/**
|
||||
* 校验交易订单满足被支付的条件
|
||||
*
|
||||
* <p>
|
||||
* 1. 交易订单未支付
|
||||
* 2. 支付单已支付
|
||||
*
|
||||
* @param id 交易订单编号
|
||||
* @param id 交易订单编号
|
||||
* @param payOrderId 支付订单编号
|
||||
* @return 交易订单
|
||||
*/
|
||||
@ -324,8 +338,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) {
|
||||
// 校验并获得交易订单(可发货)
|
||||
TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId());
|
||||
|
||||
// TODO 芋艿:logisticsId 校验存在
|
||||
// TODO 芋艿:logisticsId 校验存在 发货物流公司 fix
|
||||
DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
|
||||
if (deliveryExpress == null) {
|
||||
throw exception(DELIVERY_EXPRESS_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 更新 TradeOrderDO 状态为已发货,等待收货
|
||||
int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),
|
||||
@ -338,8 +355,32 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
// TODO 芋艿:发送订单变化的消息
|
||||
|
||||
// TODO 芋艿:发送站内信
|
||||
|
||||
// TODO 芋艿:发送站内信 fix
|
||||
// 1、获取模版编码为 order_delivery 的模版,判断是否存在 存在放回 true
|
||||
if (!notifyMessageSendApi.validateNotifyTemplate("order_delivery")) {
|
||||
// 1、1 站内信模版不存在则创建模版
|
||||
NotifyTemplateReqDTO templateReqDTO = new NotifyTemplateReqDTO();
|
||||
templateReqDTO.setName("订单发货通知模版");
|
||||
templateReqDTO.setCode("order_delivery");
|
||||
templateReqDTO.setType(NotifyTemplateTypeEnum.NOTIFICATION_MESSAGE.getType()); // 系统消息
|
||||
// 获取操作用户
|
||||
// AdminUserRespDTO user = adminUserApi.getUser(userId);
|
||||
// templateReqDTO.setNickname(user.getNickname());
|
||||
templateReqDTO.setNickname(UserTypeEnum.ADMIN.getName());
|
||||
templateReqDTO.setContent("订单:{orderId}{msg}");
|
||||
templateReqDTO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
notifyMessageSendApi.createNotifyTemplate(templateReqDTO);
|
||||
}
|
||||
// 2、构造消息
|
||||
Map<String, Object> msgMap = new HashMap<>();
|
||||
msgMap.put("orderId", deliveryReqVO.getId());
|
||||
msgMap.put("msg", TradeOrderStatusEnum.DELIVERED.getStatus());
|
||||
// 2、发送站内信
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(
|
||||
new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(userId)
|
||||
.setTemplateCode("order_delivery")
|
||||
.setTemplateParams(msgMap));
|
||||
// TODO 芋艿:OrderLog
|
||||
|
||||
// TODO 设计:like:是否要单独一个 delivery 发货单表???
|
||||
@ -349,7 +390,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
/**
|
||||
* 校验交易订单满足被发货的条件
|
||||
*
|
||||
* <p>
|
||||
* 1. 交易订单未发货
|
||||
*
|
||||
* @param id 交易订单编号
|
||||
@ -363,7 +404,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
}
|
||||
// 校验订单是否是待发货状态
|
||||
if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())
|
||||
|| ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
|
||||
|| ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
|
||||
throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
|
||||
}
|
||||
return order;
|
||||
@ -397,11 +438,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
/**
|
||||
* 校验交易订单满足可售货的条件
|
||||
*
|
||||
* <p>
|
||||
* 1. 交易订单待收货
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param id 交易订单编号
|
||||
* @param id 交易订单编号
|
||||
* @return 交易订单
|
||||
*/
|
||||
private TradeOrderDO validateOrderReceivable(Long userId, Long id) {
|
||||
@ -476,7 +517,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, Integer refundPrice) {
|
||||
// 如果退款成功,则 refundPrice 非空
|
||||
if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())
|
||||
&& refundPrice == null) {
|
||||
&& refundPrice == null) {
|
||||
throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.api.notify;
|
||||
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifyTemplateReqDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@ -27,4 +28,8 @@ public interface NotifyMessageSendApi {
|
||||
*/
|
||||
Long sendSingleMessageToMember(@Valid NotifySendSingleToUserReqDTO reqDTO);
|
||||
|
||||
|
||||
boolean validateNotifyTemplate(String orderDelivery);
|
||||
|
||||
void createNotifyTemplate(NotifyTemplateReqDTO templateReqDTO);
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.system.api.notify.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Data
|
||||
public class NotifyTemplateReqDTO {
|
||||
|
||||
@NotEmpty(message = "模版名称不能为空")
|
||||
private String name;
|
||||
|
||||
@NotNull(message = "模版编码不能为空")
|
||||
private String code;
|
||||
|
||||
@NotNull(message = "模版类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
@NotEmpty(message = "发送人名称不能为空")
|
||||
private String nickname;
|
||||
|
||||
@NotEmpty(message = "模版内容不能为空")
|
||||
private String content;
|
||||
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
private String remark;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.system.enums.notify;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 通知模板类型枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum NotifyTemplateTypeEnum {
|
||||
|
||||
/**
|
||||
* 系统消息
|
||||
*/
|
||||
SYSTEM_MESSAGE(2),
|
||||
/**
|
||||
* 通知消息
|
||||
*/
|
||||
NOTIFICATION_MESSAGE(1);
|
||||
|
||||
private final Integer type;
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.api.notify;
|
||||
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import cn.iocoder.yudao.module.system.service.notify.NotifyMessageService;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifyTemplateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.service.notify.NotifySendService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -30,4 +30,14 @@ public class NotifyMessageSendApiImpl implements NotifyMessageSendApi {
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateNotifyTemplate(String orderDelivery) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNotifyTemplate(NotifyTemplateReqDTO templateReqDTO) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user