mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product
This commit is contained in:
commit
cd4940d710
@ -31,6 +31,7 @@
|
||||
<module>yudao-spring-boot-starter-biz-sms</module>
|
||||
|
||||
<module>yudao-spring-boot-starter-biz-pay</module>
|
||||
<module>yudao-spring-boot-starter-biz-trade</module>
|
||||
<module>yudao-spring-boot-starter-biz-weixin</module>
|
||||
<module>yudao-spring-boot-starter-biz-social</module>
|
||||
<module>yudao-spring-boot-starter-biz-tenant</module>
|
||||
|
@ -0,0 +1,82 @@
|
||||
package cn.iocoder.yudao.framework.common.util.spel;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
// TODO @Chopper:和 SpringExpressionUtils 合并下
|
||||
/**
|
||||
* SpelUtil
|
||||
*
|
||||
* @author Chopper
|
||||
* @version v1.0
|
||||
* @since 2021-01-11 10:45
|
||||
*/
|
||||
public class SpelUtil {
|
||||
|
||||
|
||||
/**
|
||||
* spel表达式解析器
|
||||
*/
|
||||
private static SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
|
||||
/**
|
||||
* 参数名发现器
|
||||
*/
|
||||
private static DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
/**
|
||||
* 转换 jspl参数
|
||||
*
|
||||
* @param joinPoint
|
||||
* @param spel
|
||||
* @return
|
||||
*/
|
||||
public static String compileParams(JoinPoint joinPoint, String spel) { //Spel表达式解析日志信息
|
||||
//获得方法参数名数组
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
|
||||
String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
|
||||
if (parameterNames != null && parameterNames.length > 0) {
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
//获取方法参数值
|
||||
Object[] args = joinPoint.getArgs();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
//替换spel里的变量值为实际值, 比如 #user --> user对象
|
||||
context.setVariable(parameterNames[i], args[i]);
|
||||
}
|
||||
return spelExpressionParser.parseExpression(spel).getValue(context).toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换 jspl参数
|
||||
*
|
||||
* @param joinPoint
|
||||
* @param spel
|
||||
* @return
|
||||
*/
|
||||
public static String compileParams(JoinPoint joinPoint, Object rvt, String spel) { //Spel表达式解析日志信息
|
||||
//获得方法参数名数组
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
|
||||
String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
|
||||
if (parameterNames != null && parameterNames.length > 0) {
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
//获取方法参数值
|
||||
Object[] args = joinPoint.getArgs();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
//替换spel里的变量值为实际值, 比如 #user --> user对象
|
||||
context.setVariable(parameterNames[i], args[i]);
|
||||
}
|
||||
context.setVariable("rvt", rvt);
|
||||
return spelExpressionParser.parseExpression(spel).getValue(context).toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -37,7 +37,7 @@
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
|
||||
<artifactId>yudao-module-system-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
54
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
Normal file
54
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-framework</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>交易模块</description>
|
||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring 核心 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.framework.trade.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.trade.core.aop.AfterSaleLogAspect;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
// TODO @Chopper:和 yudao-module-trade-biz 的 framework 里
|
||||
@AutoConfiguration
|
||||
public class YudaoAfterSaleLogAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public AfterSaleLogAspect afterSaleLogAspect() {
|
||||
return new AfterSaleLogAspect();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package cn.iocoder.yudao.framework.trade.core.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 售后日志
|
||||
*
|
||||
* @author 陈賝
|
||||
* @since 2023/6/8 17:04
|
||||
*/
|
||||
@Target({ElementType.METHOD,ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface AfterSaleLog {
|
||||
|
||||
/**
|
||||
* 售后 ID
|
||||
*/
|
||||
String id();
|
||||
|
||||
// TODO @陈賝:是不是改成一个操作的枚举?
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
String operateType() default "";
|
||||
|
||||
/**
|
||||
* 日志内容
|
||||
*/
|
||||
String content() default "";
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package cn.iocoder.yudao.framework.trade.core.aop;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.spel.SpelUtil;
|
||||
import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
|
||||
import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
|
||||
import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
|
||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 记录售后日志的 AOP 切面
|
||||
*
|
||||
* @author 陈賝
|
||||
* @since 2023/6/13 13:54
|
||||
*/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
public class AfterSaleLogAspect {
|
||||
|
||||
@AfterReturning(pointcut = "@annotation(afterSaleLog)", returning = "info")
|
||||
public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog, Object info) {
|
||||
try {
|
||||
// 日志对象拼接
|
||||
Integer userType = WebFrameworkUtils.getLoginUserType();
|
||||
Long id = WebFrameworkUtils.getLoginUserId();
|
||||
Map<String, String> formatObj = spelFormat(joinPoint, info);
|
||||
TradeAfterSaleLogCreateReqDTO dto = new TradeAfterSaleLogCreateReqDTO()
|
||||
.setUserId(id).setUserType(userType)
|
||||
// MapUtil.getLong() TODO @陈賝:试试这个方法
|
||||
.setAfterSaleId(Long.valueOf(formatObj.get("id")))
|
||||
.setContent(formatObj.get("content"))
|
||||
.setOperateType(formatObj.get("operateType"));
|
||||
// 异步存入数据库 TODO 可以注入哈;
|
||||
SpringUtil.getBean(AfterSaleLogService.class).insert(dto);
|
||||
} catch (Exception exception) {
|
||||
// TODO @陈賝:日志要记录下参数哈,不然排查问题不好搞;
|
||||
log.error("日志记录错误", exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取描述信息
|
||||
*/
|
||||
public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
|
||||
Map<String, String> result = new HashMap<>(2); // TODO @陈賝:Maps.newExpectedXXX(3)
|
||||
// 售后ID
|
||||
String id = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.id());
|
||||
result.put("id", id);
|
||||
// 操作类型
|
||||
String operateType = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType());
|
||||
result.put("operateType", operateType);
|
||||
// 日志内容
|
||||
String content = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.content());
|
||||
if (StrUtil.isNotEmpty(afterSaleLogPoint.operateType())) {
|
||||
content += AfterSaleStatusEnum.valueOf(SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType())).description();
|
||||
}
|
||||
result.put("content", content);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.framework.trade.core.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 售后日志的创建 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TradeAfterSaleLogCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 关联 1:AdminUserDO 的 id 字段
|
||||
* 关联 2:MemberUserDO 的 id 字段
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
private Integer userType;
|
||||
/**
|
||||
* 售后编号
|
||||
*/
|
||||
private Long afterSaleId;
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
private String operateType;
|
||||
/**
|
||||
* 操作明细
|
||||
*/
|
||||
private String content;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.framework.trade.core.enums;
|
||||
|
||||
/**
|
||||
* 售后状态的枚举
|
||||
*
|
||||
* @author 陈賝
|
||||
* @since 2023/6/13 13:53
|
||||
*/
|
||||
public enum AfterSaleStatusEnum {
|
||||
|
||||
/**
|
||||
* 申请中
|
||||
*/
|
||||
APPLY("申请中");
|
||||
|
||||
private final String description;
|
||||
|
||||
AfterSaleStatusEnum(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.framework.trade.core.service;
|
||||
|
||||
import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||
|
||||
// TODO @陈賝:类注释
|
||||
public interface AfterSaleLogService {
|
||||
|
||||
/**
|
||||
* 创建售后日志
|
||||
*
|
||||
* @param logDTO 日志记录
|
||||
* @author 陈賝
|
||||
* @since 2023/6/12 14:18
|
||||
*/
|
||||
// TODO @陈賝:createLog 方法名
|
||||
void insert(TradeAfterSaleLogCreateReqDTO logDTO);
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration
|
@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.api.comment;
|
||||
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
|
||||
/**
|
||||
* 产品评论 API 接口
|
||||
@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
|
||||
*/
|
||||
public interface ProductCommentApi {
|
||||
|
||||
// TODO @puhui:Long orderId 放到 createReqDTO 里噶?
|
||||
/**
|
||||
* 创建评论
|
||||
*
|
||||
@ -16,6 +17,6 @@ public interface ProductCommentApi {
|
||||
* @param orderId 订单 id
|
||||
* @return 返回评论创建后的 id
|
||||
*/
|
||||
Long createComment(CommentCreateReqDTO createReqDTO, Long orderId);
|
||||
Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId);
|
||||
|
||||
}
|
||||
|
@ -10,71 +10,64 @@ import java.util.List;
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Data
|
||||
public class CommentCreateReqDTO {
|
||||
public class ProductCommentCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 是否匿名
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Boolean anonymous;
|
||||
|
||||
private Long skuId;
|
||||
/**
|
||||
* 交易订单项编号
|
||||
*/
|
||||
private Long orderItemId;
|
||||
|
||||
// TODO @huihui:spuId、spuName 去查询哇?通过 skuId
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Long spuId;
|
||||
|
||||
/**
|
||||
* 商品 SPU 名称
|
||||
*/
|
||||
private String spuName;
|
||||
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 评分星级 1-5 分
|
||||
*/
|
||||
private Integer scores;
|
||||
|
||||
/**
|
||||
* 描述星级 1-5 分
|
||||
*/
|
||||
private Integer descriptionScores;
|
||||
|
||||
/**
|
||||
* 服务星级 1-5 分
|
||||
*/
|
||||
private Integer benefitScores;
|
||||
|
||||
/**
|
||||
* 评论内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 评论图片地址数组,以逗号分隔最多上传9张
|
||||
* 评论图片地址数组,以逗号分隔最多上传 9 张
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
|
||||
/**
|
||||
* 是否匿名
|
||||
*/
|
||||
private Boolean anonymous;
|
||||
/**
|
||||
* 评价人
|
||||
*/
|
||||
private Long userId;
|
||||
// TODO @puhui999:是不是 userNickname、userAvatar 去掉?通过 userId 查询
|
||||
/**
|
||||
* 评价人名称
|
||||
*/
|
||||
private String userNickname;
|
||||
|
||||
/**
|
||||
* 评价人头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 评价人
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.module.product.api.comment;
|
||||
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
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;
|
||||
@ -17,12 +17,14 @@ import javax.annotation.Resource;
|
||||
@Service
|
||||
@Validated
|
||||
public class ProductCommentApiImpl implements ProductCommentApi {
|
||||
|
||||
@Resource
|
||||
private ProductCommentService productCommentService;
|
||||
|
||||
@Override
|
||||
public Long createComment(CommentCreateReqDTO createReqDTO, Long orderId) {
|
||||
public Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId) {
|
||||
ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId);
|
||||
return productCommentService.createComment(commentDO);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,15 +30,15 @@ public class ProductCommentBaseVO {
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "评分星级 1-5分", required = true, example = "5")
|
||||
@Schema(description = "评分星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5分", required = true, example = "5")
|
||||
@Schema(description = "描述星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
||||
@Schema(description = "服务星级 1-5分", required = true, example = "5")
|
||||
@Schema(description = "服务星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级分不能为空")
|
||||
private Integer benefitScores;
|
||||
|
||||
@ -46,8 +46,8 @@ public class ProductCommentBaseVO {
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过9张")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import javax.validation.constraints.NotNull;
|
||||
@ToString(callSuper = true)
|
||||
public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
|
||||
|
||||
// TODO @puhui999:是不是也放到父类里?
|
||||
@Schema(description = "评价人", required = true, example = "16868")
|
||||
@NotNull(message = "评价人不能为空")
|
||||
private Long userId;
|
||||
|
@ -31,7 +31,7 @@ public class ProductCommentPageReqVO extends PageParam {
|
||||
@Schema(description = "商品SPU名称", example = "感冒药")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "评分星级 1-5分", example = "5")
|
||||
@Schema(description = "评分星级 1-5 分", example = "5")
|
||||
@InEnum(ProductCommentScoresEnum.class)
|
||||
private Integer scores;
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
|
||||
@Schema(description = "订单项编号", required = true, example = "24965")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true, example = "false")
|
||||
@Schema(description = "是否匿名", required = true, example = "false")
|
||||
private Boolean anonymous;
|
||||
|
||||
@Schema(description = "交易订单编号", required = true, example = "24428")
|
||||
|
@ -36,6 +36,7 @@ public class AppProductCommentController {
|
||||
@Resource
|
||||
private ProductCommentService productCommentService;
|
||||
|
||||
// TODO @puhui999:可以实现下
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得最近的 n 条商品评价")
|
||||
@Parameters({
|
||||
@ -44,7 +45,6 @@ public class AppProductCommentController {
|
||||
})
|
||||
public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
|
||||
@RequestParam(value = "count", defaultValue = "10") Integer count) {
|
||||
|
||||
List<AppProductPropertyValueDetailRespVO> list = new ArrayList<>();
|
||||
|
||||
AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO();
|
||||
@ -101,6 +101,7 @@ public class AppProductCommentController {
|
||||
return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
|
||||
}
|
||||
|
||||
// TODO @puhui:get-statistics;方法改成 getCommentStatistics;getCommentPageTabsCount 也改掉哈
|
||||
@GetMapping("/getCommentStatistics")
|
||||
@Operation(summary = "获得商品的评价统计")
|
||||
public CommonResult<AppCommentStatisticsRespVO> getCommentPage(@Valid @RequestParam("spuId") Long spuId) {
|
||||
|
@ -8,11 +8,6 @@ import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 用户 APP - 商品评价分页 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "用户APP - 商品评价分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -23,12 +18,10 @@ public class AppCommentPageReqVO extends PageParam {
|
||||
* 好评
|
||||
*/
|
||||
public static final Integer GOOD_COMMENT = 1;
|
||||
|
||||
/**
|
||||
* 中评
|
||||
*/
|
||||
public static final Integer MEDIOCRE_COMMENT = 2;
|
||||
|
||||
/**
|
||||
* 差评
|
||||
*/
|
||||
|
@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* APP 商品评价页评论分类数统计 Response VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "APP - 商品评价页评论分类数统计 Response VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
|
@ -8,11 +8,6 @@ import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户APP - 商品评价创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "用户APP - 商品评价创建 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@ -26,36 +21,36 @@ public class AppProductCommentCreateReqVO {
|
||||
@NotNull(message = "交易订单项编号不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
@Schema(description = "商品SPU编号", required = true, example = "91192")
|
||||
@Schema(description = "商品 SPU 编号", required = true, example = "91192")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖")
|
||||
@Schema(description = "商品 SPU 名称", required = true, example = "清凉丝滑小短袖")
|
||||
@NotNull(message = "商品SPU名称不能为空")
|
||||
private String spuName;
|
||||
|
||||
@Schema(description = "商品SKU编号", required = true, example = "81192")
|
||||
@Schema(description = "商品 SKU 编号", required = true, example = "81192")
|
||||
@NotNull(message = "商品SKU编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "评分星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5分不能为空")
|
||||
@Schema(description = "评分星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5 分不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5分不能为空")
|
||||
@Schema(description = "描述星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5 分不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
||||
@Schema(description = "服务星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5分不能为空")
|
||||
@Schema(description = "服务星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5 分不能为空")
|
||||
private Integer benefitScores;
|
||||
|
||||
@Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过9张")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class AppProductCommentRespVO {
|
||||
@Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶")
|
||||
private String additionalContent;
|
||||
|
||||
@Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Schema(description = "追评评价图片地址数组,以逗号分隔最多上传 9 张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
private List<String> additionalPicUrls;
|
||||
|
||||
@Schema(description = "追加评价时间")
|
||||
@ -86,24 +86,24 @@ public class AppProductCommentRespVO {
|
||||
@Schema(description = "商品 SKU 属性", required = true)
|
||||
private List<AppProductPropertyValueDetailRespVO> skuProperties;
|
||||
|
||||
@Schema(description = "评分星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5分不能为空")
|
||||
@Schema(description = "评分星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5 分不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5分不能为空")
|
||||
@Schema(description = "描述星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5 分不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
||||
@Schema(description = "服务星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5分不能为空")
|
||||
@Schema(description = "服务星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5 分不能为空")
|
||||
private Integer benefitScores;
|
||||
|
||||
@Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过9张")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.product.convert.comment;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
|
||||
@ -49,7 +49,7 @@ public interface ProductCommentConvert {
|
||||
*
|
||||
* @param descriptionScores 描述星级
|
||||
* @param benefitScores 服务星级
|
||||
* @return {@link Integer}
|
||||
* @return 综合评分
|
||||
*/
|
||||
@Named("convertScores")
|
||||
default Integer convertScores(Integer descriptionScores, Integer benefitScores) {
|
||||
@ -61,7 +61,7 @@ public interface ProductCommentConvert {
|
||||
|
||||
@Mapping(target = "orderId", source = "orderId")
|
||||
@Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
|
||||
ProductCommentDO convert(CommentCreateReqDTO createReqDTO, Long orderId);
|
||||
ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, Long orderId);
|
||||
|
||||
@Mapping(target = "userId", constant = "0L")
|
||||
@Mapping(target = "orderId", constant = "0L")
|
||||
|
@ -97,7 +97,7 @@ public class ProductCommentDO extends BaseDO {
|
||||
/**
|
||||
* 评分星级
|
||||
*
|
||||
* 1-5分
|
||||
* 1-5 分
|
||||
*/
|
||||
private Integer scores;
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
|
||||
}
|
||||
|
||||
// TODO 芋艿:在看看这块
|
||||
// TODO @puhui999:直接使用 scores 来算好评、中评、差评
|
||||
static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
|
||||
// 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8
|
||||
if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
|
||||
|
@ -54,7 +54,8 @@ public interface ProductCommentService {
|
||||
PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
|
||||
|
||||
/**
|
||||
* 创建商品评论 后台管理员创建评论使用
|
||||
* 创建商品评论
|
||||
* 后台管理员创建评论使用
|
||||
*
|
||||
* @param createReqVO 商品评价创建 Request VO 对象
|
||||
*/
|
||||
|
@ -86,6 +86,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createComment(ProductCommentCreateReqVO createReqVO) {
|
||||
// 校验订单
|
||||
// TODO @puhui999:不校验哈;尽可能解耦
|
||||
Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId());
|
||||
// 校验评论
|
||||
validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId);
|
||||
@ -104,8 +105,6 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
return commentDO.getId();
|
||||
}
|
||||
|
||||
// TODO 只有创建和更新诶 要不要删除接口
|
||||
|
||||
private void validateComment(Long spuId, Long userId, Long orderId) {
|
||||
ProductSpuDO spu = productSpuService.getSpu(spuId);
|
||||
if (null == spu) {
|
||||
@ -144,6 +143,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
|
||||
public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
|
||||
PageResult<AppProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(
|
||||
productCommentMapper.selectPage(pageVO, visible));
|
||||
// TODO @puhui999:要不这块放到 controller 里拼接?
|
||||
Set<Long> skuIds = result.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
|
||||
List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
|
||||
Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
|
||||
|
@ -126,6 +126,7 @@ CREATE TABLE IF NOT EXISTS `product_property_value` (
|
||||
PRIMARY KEY("id")
|
||||
) COMMENT '规格值';
|
||||
|
||||
-- TODO @puhui999:格式不太对哈
|
||||
CREATE TABLE IF NOT EXISTS `product_comment`
|
||||
(
|
||||
`id`
|
||||
@ -166,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `product_comment`
|
||||
(
|
||||
1
|
||||
) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏',
|
||||
`scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分',
|
||||
`scores` tinyint DEFAULT NULL COMMENT '评分星级1-5 分',
|
||||
`description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星',
|
||||
`benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星',
|
||||
`content` varchar
|
||||
|
@ -38,7 +38,7 @@ public class AppCombinationActivityController {
|
||||
activity1.setName("618 大拼团");
|
||||
activity1.setUserSize(3);
|
||||
activity1.setSpuId(2048L);
|
||||
activity1.setPicUrl("商品图片地址");
|
||||
activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
|
||||
activity1.setMarketPrice(50);
|
||||
activity1.setCombinationPrice(100);
|
||||
activityList.add(activity1);
|
||||
@ -48,7 +48,7 @@ public class AppCombinationActivityController {
|
||||
activity2.setName("双十一拼团");
|
||||
activity2.setUserSize(5);
|
||||
activity2.setSpuId(4096L);
|
||||
activity2.setPicUrl("商品图片地址");
|
||||
activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
|
||||
activity2.setMarketPrice(100);
|
||||
activity2.setCombinationPrice(200);
|
||||
activityList.add(activity2);
|
||||
|
@ -1,7 +1,11 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.AppSeckillActivitiDetailRespVO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -23,12 +27,65 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
@Validated
|
||||
public class AppSeckillActivityController {
|
||||
|
||||
@GetMapping("/get-now")
|
||||
@Operation(summary = "获得当前秒杀活动") // 提供给首页使用
|
||||
// TODO 芋艿:需要增加 spring cache
|
||||
public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
|
||||
AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
|
||||
respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59"));
|
||||
List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
|
||||
AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
|
||||
activity1.setId(1L);
|
||||
activity1.setName("618 大秒杀");
|
||||
activity1.setSpuId(2048L);
|
||||
activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
|
||||
activity1.setMarketPrice(50);
|
||||
activity1.setSeckillPrice(100);
|
||||
activityList.add(activity1);
|
||||
|
||||
AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
|
||||
activity2.setId(2L);
|
||||
activity2.setName("双十一大秒杀");
|
||||
activity2.setSpuId(4096L);
|
||||
activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
|
||||
activity2.setMarketPrice(100);
|
||||
activity2.setSeckillPrice(200);
|
||||
activityList.add(activity2);
|
||||
respVO.setActivities(activityList);
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得秒杀活动分页")
|
||||
// TODO @芋艿:分页参数
|
||||
public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage() {
|
||||
List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
|
||||
AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
|
||||
activity1.setId(1L);
|
||||
activity1.setName("618 大秒杀");
|
||||
activity1.setSpuId(2048L);
|
||||
activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
|
||||
activity1.setMarketPrice(50);
|
||||
activity1.setSeckillPrice(100);
|
||||
activityList.add(activity1);
|
||||
|
||||
AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
|
||||
activity2.setId(2L);
|
||||
activity2.setName("双十一大秒杀");
|
||||
activity2.setSpuId(4096L);
|
||||
activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
|
||||
activity2.setMarketPrice(100);
|
||||
activity2.setSeckillPrice(200);
|
||||
activityList.add(activity2);
|
||||
return success(new PageResult<>(activityList, 100L));
|
||||
}
|
||||
|
||||
@GetMapping("/get-detail")
|
||||
@Operation(summary = "获得秒杀活动明细")
|
||||
@Parameter(name = "id", description = "活动编号", required = true, example = "1024")
|
||||
public CommonResult<AppSeckillActivitiDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
|
||||
public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
|
||||
// TODO 芋艿:如果禁用的时候,需要抛出异常;
|
||||
AppSeckillActivitiDetailRespVO obj = new AppSeckillActivitiDetailRespVO();
|
||||
AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO();
|
||||
// 设置其属性的值
|
||||
obj.setId(id);
|
||||
obj.setName("晚九点限时秒杀");
|
||||
@ -37,9 +94,9 @@ public class AppSeckillActivityController {
|
||||
obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0));
|
||||
obj.setSpuId(633L);
|
||||
// 创建一个Product对象的列表
|
||||
List<AppSeckillActivitiDetailRespVO.Product> productList = new ArrayList<>();
|
||||
List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>();
|
||||
// 创建三个新的Product对象并设置其属性的值
|
||||
AppSeckillActivitiDetailRespVO.Product product1 = new AppSeckillActivitiDetailRespVO.Product();
|
||||
AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product();
|
||||
product1.setSkuId(1L);
|
||||
product1.setSeckillPrice(100);
|
||||
product1.setQuota(50);
|
||||
@ -47,7 +104,7 @@ public class AppSeckillActivityController {
|
||||
// 将第一个Product对象添加到列表中
|
||||
productList.add(product1);
|
||||
// 创建第二个Product对象并设置其属性的值
|
||||
AppSeckillActivitiDetailRespVO.Product product2 = new AppSeckillActivitiDetailRespVO.Product();
|
||||
AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product();
|
||||
product2.setSkuId(2L);
|
||||
product2.setSeckillPrice(200);
|
||||
product2.setQuota(100);
|
||||
@ -55,7 +112,7 @@ public class AppSeckillActivityController {
|
||||
// 将第二个Product对象添加到列表中
|
||||
productList.add(product2);
|
||||
// 创建第三个Product对象并设置其属性的值
|
||||
AppSeckillActivitiDetailRespVO.Product product3 = new AppSeckillActivitiDetailRespVO.Product();
|
||||
AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product();
|
||||
product3.setSkuId(3L);
|
||||
product3.setSeckillPrice(300);
|
||||
product3.setQuota(150);
|
||||
|
@ -0,0 +1,33 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "用户 App - 秒杀时间段")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/seckill-config")
|
||||
@Validated
|
||||
public class AppSeckillConfigController {
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得秒杀时间段列表")
|
||||
public CommonResult<List<AppSeckillConfigRespVO>> getConfigList() {
|
||||
return success(Arrays.asList(
|
||||
new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59"),
|
||||
new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
|
||||
new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("23:59")
|
||||
));
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@ -6,9 +6,9 @@ import lombok.Data;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "用户 App - 秒杀活动 Response VO")
|
||||
@Schema(description = "用户 App - 秒杀活动的详细 Response VO")
|
||||
@Data
|
||||
public class AppSeckillActivitiDetailRespVO {
|
||||
public class AppSeckillActivityDetailRespVO {
|
||||
|
||||
@Schema(description = "秒杀活动编号", required = true, example = "1024")
|
||||
private Long id;
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "用户 App - 当前秒杀活动 Response VO")
|
||||
@Data
|
||||
public class AppSeckillActivityNowRespVO {
|
||||
|
||||
@Schema(description = "秒杀时间段", required = true)
|
||||
private AppSeckillConfigRespVO config;
|
||||
|
||||
@Schema(description = "秒杀活动数组", required = true)
|
||||
private List<AppSeckillActivityRespVO> activities;
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "用户 App - 秒杀活动 Response VO")
|
||||
@Data
|
||||
public class AppSeckillActivityRespVO {
|
||||
|
||||
@Schema(description = "秒杀活动编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "商品 SPU 编号", required = true, example = "2048")
|
||||
private Long spuId;
|
||||
|
||||
@Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取
|
||||
private String picUrl;
|
||||
|
||||
@Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
|
||||
private Integer marketPrice;
|
||||
|
||||
@Schema(description = "秒杀金额,单位:分", required = true, example = "100") // 从秒杀商品里取最低价
|
||||
private Integer seckillPrice;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "用户 App - 秒杀时间段 Response VO")
|
||||
@Data
|
||||
public class AppSeckillConfigRespVO {
|
||||
|
||||
@Schema(description = "秒杀时间段编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "开始时间点", required = true, example = "09:00")
|
||||
private String startTime;
|
||||
@Schema(description = "结束时间点", required = true, example = "09:59")
|
||||
private String endTime;
|
||||
|
||||
}
|
@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
|
||||
@Getter
|
||||
public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
|
||||
|
||||
APPLY(10,"申请中", // 【申请售后】
|
||||
"会员申请退款"),
|
||||
SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】
|
||||
"商家同意退款"),
|
||||
BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】
|
||||
"会员填写退货物流信息"),
|
||||
WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】
|
||||
"商家收货"),
|
||||
COMPLETE(50, "完成", // 完成退款【退款成功】
|
||||
"商家确认退款"),
|
||||
|
||||
BUYER_CANCEL(61, "买家取消售后", // 【买家取消】
|
||||
"会员取消退款"),
|
||||
SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】
|
||||
"商家拒绝退款"),
|
||||
SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】
|
||||
"商家拒绝收货"),
|
||||
/**
|
||||
* 【申请售后】
|
||||
*/
|
||||
APPLY(10,"申请中", "会员申请退款"),
|
||||
/**
|
||||
* 卖家通过售后;【商品待退货】
|
||||
*/
|
||||
SELLER_AGREE(20, "卖家通过", "商家同意退款"),
|
||||
/**
|
||||
* 买家已退货,等待卖家收货;【商家待收货】
|
||||
*/
|
||||
BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
|
||||
/**
|
||||
* 卖家已收货,等待平台退款;等待退款【等待退款】
|
||||
*/
|
||||
WAIT_REFUND(40, "等待平台退款", "商家收货"),
|
||||
/**
|
||||
* 完成退款【退款成功】
|
||||
*/
|
||||
COMPLETE(50, "完成", "商家确认退款"),
|
||||
/**
|
||||
* 【买家取消】
|
||||
*/
|
||||
BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
|
||||
/**
|
||||
* 卖家拒绝售后;商家拒绝【商家拒绝】
|
||||
*/
|
||||
SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
|
||||
/**
|
||||
* 卖家拒绝收货,终止售后;【商家拒收货】
|
||||
*/
|
||||
SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();
|
||||
|
@ -58,6 +58,11 @@
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
@ -93,6 +98,7 @@
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
|
||||
@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
|
||||
import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
|
||||
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
|
||||
@ -110,4 +112,20 @@ public class TradeAfterSaleController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @陈賝:后续要删除下
|
||||
/**
|
||||
* 售后日志测试
|
||||
*
|
||||
* @param createReqVO
|
||||
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Long>
|
||||
* @author 陈賝
|
||||
* @date 2023/6/14 21:39
|
||||
*/
|
||||
@PostMapping(value = "/create")
|
||||
@AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
|
||||
public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
|
||||
return success(1L);
|
||||
// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@ -31,6 +32,14 @@ public class AppTradeAfterSaleCreateReqVO {
|
||||
@NotNull(message = "申请原因不能为空")
|
||||
private String applyReason;
|
||||
|
||||
// TODO @陈賝:这个参数不应该有呀。
|
||||
/**
|
||||
* @see AfterSaleStatusEnum
|
||||
*/
|
||||
@Schema(description = "操作类型", required = true, example = "1")
|
||||
@NotNull(message = "操作类型不能为空")
|
||||
private String operateType;
|
||||
|
||||
@Schema(description = "补充描述", example = "商品质量不好")
|
||||
private String applyDescription;
|
||||
|
||||
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
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;
|
||||
@ -49,13 +48,12 @@ public class AppTradeOrderController {
|
||||
|
||||
@Resource
|
||||
private ProductPropertyValueApi productPropertyValueApi;
|
||||
@Resource
|
||||
private ProductCommentApi productCommentApi;
|
||||
|
||||
@Resource
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
|
||||
@Resource
|
||||
private ProductCommentApi productCommentApi;
|
||||
|
||||
@GetMapping("/settlement")
|
||||
@Operation(summary = "获得订单结算信息")
|
||||
@PreAuthenticated
|
||||
@ -141,6 +139,7 @@ public class AppTradeOrderController {
|
||||
@Operation(summary = "创建交易订单项的评价")
|
||||
public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
|
||||
// 校验订单项,订单项存在订单就存在
|
||||
// TODO @puhui999:要去查询订单是不是自己的;不然别人模拟请求哈;
|
||||
TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId());
|
||||
if (item == null) {
|
||||
throw exception(ORDER_ITEM_NOT_FOUND);
|
||||
@ -149,6 +148,6 @@ public class AppTradeOrderController {
|
||||
return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId()));
|
||||
}
|
||||
|
||||
// TODO 合并代码后发现只有商家回复功能 用户追评不要了吗?
|
||||
// TODO 合并代码后发现只有商家回复功能 用户追评不要了吗?不要了哈;
|
||||
|
||||
}
|
||||
|
@ -7,11 +7,6 @@ import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品评价创建 Request VO
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "用户APP - 商品评价创建 Request VO")
|
||||
@Data
|
||||
public class AppTradeOrderItemCommentCreateReqVO {
|
||||
@ -24,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO {
|
||||
@NotNull(message = "交易订单项编号不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
// TODO @puhui:spuId、spuName、skuId 直接查询出来;
|
||||
@Schema(description = "商品SPU编号", required = true, example = "29502")
|
||||
@NotNull(message = "商品SPU编号不能为空")
|
||||
private Long spuId;
|
||||
@ -36,30 +32,32 @@ public class AppTradeOrderItemCommentCreateReqVO {
|
||||
@NotNull(message = "商品SKU编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@Schema(description = "评分星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5分不能为空")
|
||||
@Schema(description = "评分星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "评分星级 1-5 分不能为空")
|
||||
private Integer scores;
|
||||
|
||||
@Schema(description = "描述星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5分不能为空")
|
||||
@Schema(description = "描述星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "描述星级 1-5 分不能为空")
|
||||
private Integer descriptionScores;
|
||||
|
||||
@Schema(description = "服务星级 1-5分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5分不能为空")
|
||||
@Schema(description = "服务星级 1-5 分", required = true, example = "5")
|
||||
@NotNull(message = "服务星级 1-5 分不能为空")
|
||||
private Integer benefitScores;
|
||||
|
||||
@Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)")
|
||||
@NotNull(message = "评论内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过9张")
|
||||
@Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
|
||||
@Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
|
||||
private List<String> picUrls;
|
||||
|
||||
@Schema(description = "评价人名称", required = true, example = "小姑凉")
|
||||
@NotNull(message = "评价人名称不能为空")
|
||||
private String userNickname;
|
||||
|
||||
// TODO @puhui:userAvatar、userAvatar、userId 直接查询出来;
|
||||
|
||||
@Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
|
||||
@NotNull(message = "评价人头像不能为空")
|
||||
private String userAvatar;
|
||||
|
@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
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;
|
||||
@ -227,6 +227,7 @@ public interface TradeOrderConvert {
|
||||
|
||||
AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean);
|
||||
|
||||
// TODO 芋艿:可简化
|
||||
default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
|
||||
List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) {
|
||||
AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
|
||||
@ -258,7 +259,7 @@ public interface TradeOrderConvert {
|
||||
|
||||
AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
|
||||
|
||||
CommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
|
||||
ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
|
||||
|
||||
default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
|
||||
List<TradeCartDO> cartList) {
|
||||
@ -302,5 +303,4 @@ public interface TradeOrderConvert {
|
||||
|
||||
AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
|
||||
|
||||
|
||||
}
|
||||
|
@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
|
||||
*/
|
||||
private Long afterSaleId;
|
||||
/**
|
||||
* 订单编号
|
||||
*
|
||||
* 关联 {@link TradeOrderDO#getId()}
|
||||
* 操作类型 {@link TradeAfterSaleStatusEnum}
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 订单项编号
|
||||
*
|
||||
* 关联 {@link TradeOrderItemDO#getId()}
|
||||
*/
|
||||
private Long orderItemId;
|
||||
/**
|
||||
* 售后状态(之前)
|
||||
*
|
||||
* 枚举 {@link TradeAfterSaleStatusEnum}
|
||||
*/
|
||||
private Integer beforeStatus;
|
||||
/**
|
||||
* 售后状态(之后)
|
||||
*
|
||||
* 枚举 {@link TradeAfterSaleStatusEnum}
|
||||
*/
|
||||
private Integer afterStatus;
|
||||
private String operateType;
|
||||
/**
|
||||
* 操作明细
|
||||
*/
|
||||
|
@ -5,6 +5,8 @@ import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
|
||||
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
|
||||
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
|
||||
@ -26,6 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Validated
|
||||
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
||||
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
|
||||
|
||||
@Resource
|
||||
private TradeOrderService tradeOrderService;
|
||||
@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
||||
/**
|
||||
* 校验交易订单项是否可以申请售后
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param userId 用户编号
|
||||
* @param createReqVO 售后创建信息
|
||||
* @return 交易订单项
|
||||
*/
|
||||
@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
||||
}
|
||||
// 如果是【退货退款】的情况,需要额外校验是否发货
|
||||
if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
|
||||
&& !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
|
||||
&& !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
|
||||
throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
|
||||
}
|
||||
return orderItem;
|
||||
@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
||||
TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
|
||||
afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
|
||||
afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
|
||||
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
|
||||
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
|
||||
// TODO 退还积分
|
||||
tradeAfterSaleMapper.insert(afterSale);
|
||||
|
||||
@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
||||
TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
|
||||
Integer beforeStatus, Integer afterStatus) {
|
||||
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)
|
||||
.setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())
|
||||
.setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
|
||||
.setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());
|
||||
tradeAfterSaleLogMapper.insert(afterSaleLog);
|
||||
TradeAfterSaleLogCreateReqDTO logDTO = new TradeAfterSaleLogCreateReqDTO()
|
||||
.setUserId(userId)
|
||||
.setUserType(userType)
|
||||
.setAfterSaleId(afterSale.getId())
|
||||
.setOperateType(afterStatus.toString());
|
||||
// TODO 废弃,待删除
|
||||
this.insert(logDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志记录
|
||||
*
|
||||
* @param logDTO 日志记录
|
||||
* @author 陈賝
|
||||
* @date 2023/6/12 14:18
|
||||
*/
|
||||
@Override
|
||||
@Async
|
||||
public void insert(TradeAfterSaleLogCreateReqDTO logDTO) {
|
||||
try {
|
||||
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
|
||||
.setUserId(logDTO.getUserId())
|
||||
.setUserType(logDTO.getUserType())
|
||||
.setAfterSaleId(logDTO.getAfterSaleId())
|
||||
.setOperateType(logDTO.getOperateType())
|
||||
.setContent(logDTO.getContent());
|
||||
tradeAfterSaleLogMapper.insert(afterSaleLog);
|
||||
}catch (Exception exception){
|
||||
log.error("日志记录错误", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
|
||||
AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
|
||||
.setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
|
||||
.setApplyReason("退钱").setApplyDescription("快退")
|
||||
.setOperateType("APPLY")
|
||||
.setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
|
||||
// mock 方法(交易订单项)
|
||||
TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
|
||||
@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
|
||||
assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
|
||||
assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
|
||||
assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
|
||||
assertNull(afterSaleLog.getBeforeStatus());
|
||||
assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
|
||||
// assertNull(afterSaleLog.getBeforeStatus());
|
||||
// assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
|
||||
assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,11 @@
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- 支付服务 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-pay-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-pay-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 微信公众号模块。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
@ -68,25 +68,19 @@
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- 商城相关模块。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-product-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-trade-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-point-biz</artifactId>
|
||||
<artifactId>yudao-module-promotion-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-product-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-trade-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user