From 35528e8267ce549ff4bc658ee51d0788afc21089 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 19 Nov 2022 20:43:59 +0800 Subject: [PATCH] =?UTF-8?q?trade=EF=BC=9A=E3=80=90=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E5=94=AE=E5=90=8E=E3=80=91=E6=9F=A5=E8=AF=A2=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/CommonStatusEnum.java | 1 - .../service/codegen/inner/CodegenBuilder.java | 41 ++++++ .../aftersale/TradeAfterSaleStatusEnum.java | 12 +- .../order/TradeOrderAfterSaleStatusEnum.java | 12 +- .../enums/order/TradeOrderCancelTypeEnum.java | 12 +- .../TradeOrderItemAfterSaleStatusEnum.java | 12 +- .../enums/order/TradeOrderStatusEnum.java | 12 +- .../trade/enums/order/TradeOrderTypeEnum.java | 12 +- .../aftersale/TradeAfterSaleController.java | 14 +++ .../aftersale/vo/TradeAfterSaleBaseVO.java | 119 ++++++++++++++++++ .../aftersale/vo/TradeAfterSalePageReqVO.java | 45 +++++++ .../aftersale/vo/TradeAfterSaleRespVO.java | 23 ++++ .../controller/admin/base/package-info.java | 4 + .../base/property/ProductPropertyRespVO.java | 17 +++ .../aftersale/TradeAfterSaleConvert.java | 4 + .../aftersale/TradeAfterSaleDO.java | 6 + .../dataobject/order/TradeOrderItemDO.java | 3 +- .../mysql/aftersale/TradeAfterSaleMapper.java | 14 +++ .../aftersale/TradeAfterSaleService.java | 11 ++ .../aftersale/TradeAfterSaleServiceImpl.java | 7 ++ .../aftersale/TradeAfterSaleServiceTest.java | 45 +++++++ .../src/test/resources/sql/create_tables.sql | 1 + 22 files changed, 419 insertions(+), 8 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/property/ProductPropertyRespVO.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/CommonStatusEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/CommonStatusEnum.java index cd1b9dc5e..7b07fa1f5 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/CommonStatusEnum.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/CommonStatusEnum.java @@ -20,7 +20,6 @@ public enum CommonStatusEnum implements IntArrayValuable { public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray(); - /** * 状态值 */ diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java index 90f5816f3..8293ffef0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java @@ -18,6 +18,8 @@ import org.springframework.stereotype.Component; import java.util.*; import static cn.hutool.core.text.CharSequenceUtil.*; +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.hutool.core.util.RandomUtil.randomInt; /** * 代码生成器的 Builder,负责: @@ -128,6 +130,7 @@ public class CodegenBuilder { // 初始化 Column 列的默认字段 processColumnOperation(column); // 处理 CRUD 相关的字段的默认值 processColumnUI(column); // 处理 UI 相关的字段的默认值 + processColumnExample(column); // 处理字段的 swagger example 示例 } return columns; } @@ -169,4 +172,42 @@ public class CodegenBuilder { } } + /** + * 处理字段的 swagger example 示例 + * + * @param column 字段 + */ + private void processColumnExample(CodegenColumnDO column) { + // id、price、count 等可能是整数的后缀 + if (StrUtil.endWithAnyIgnoreCase(column.getJavaField(), "id", "price", "count")) { + column.setExample(String.valueOf(randomInt(1, Short.MAX_VALUE))); + return; + } + // name + if (StrUtil.endWithIgnoreCase(column.getJavaField(), "name")) { + column.setExample(randomEle(new String[]{"张三", "李四", "王五", "赵六", "芋艿"})); + return; + } + // status + if (StrUtil.endWithAnyIgnoreCase(column.getJavaField(), "status", "type")) { + column.setExample(randomEle(new String[]{"1", "2"})); + return; + } + // url + if (StrUtil.endWithIgnoreCase(column.getColumnName(), "url")) { + column.setExample("https://www.iocoder.cn"); + return; + } + // reason + if (StrUtil.endWithIgnoreCase(column.getColumnName(), "reason")) { + column.setExample(randomEle(new String[]{"不喜欢", "不对", "不好", "不香"})); + return; + } + // description、memo、remark + if (StrUtil.endWithAnyIgnoreCase(column.getColumnName(), "description", "memo", "remark")) { + column.setExample(randomEle(new String[]{"你猜", "随便", "你说的对"})); + return; + } + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java index e03520ea7..bae0b9f1c 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.enums.aftersale; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; + /** * 售后状态的枚举 * @@ -12,7 +15,7 @@ import lombok.Getter; */ @AllArgsConstructor @Getter -public enum TradeAfterSaleStatusEnum { +public enum TradeAfterSaleStatusEnum implements IntArrayValuable { APPLY(10,"申请中"), SELLER_AGREE(20, "卖家通过"), // 卖家通过售后 @@ -25,6 +28,8 @@ public enum TradeAfterSaleStatusEnum { SELLER_REFUSE(63,"卖家拒绝收货"), // 卖家拒绝收货,终止售后 ; + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray(); + /** * 状态 */ @@ -34,4 +39,9 @@ public enum TradeAfterSaleStatusEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java index d3388bfcb..40402b6f8 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.enums.order; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; + /** * 交易订单 - 售后状态 * @@ -10,12 +13,14 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor @Getter -public enum TradeOrderAfterSaleStatusEnum { +public enum TradeOrderAfterSaleStatusEnum implements IntArrayValuable { NONE(0, "未退款"), PART(1, "部分退款"), ALL(2, "全部退款"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderAfterSaleStatusEnum::getStatus).toArray(); + /** * 状态值 */ @@ -25,4 +30,9 @@ public enum TradeOrderAfterSaleStatusEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java index 389fc75b0..1dabec194 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.enums.order; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; + /** * 交易订单 - 关闭类型 * @@ -10,13 +13,15 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor @Getter -public enum TradeOrderCancelTypeEnum { +public enum TradeOrderCancelTypeEnum implements IntArrayValuable { PAY_TIMEOUT(10, "超时未支付"), AFTER_SALE_CLOSE(20, "退款关闭"), MEMBER_CANCEL(30, "买家取消"), PAY_ON_DELIVERY(40, "已通过货到付款交易"),; // TODO 芋艿:这个类型,是不是可以去掉 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderCancelTypeEnum::getType).toArray(); + /** * 关闭类型 */ @@ -26,4 +31,9 @@ public enum TradeOrderCancelTypeEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java index 70d7bf4bc..f1226f5b1 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.trade.enums.order; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; + /** * 交易订单项 - 售后状态 * @@ -11,12 +14,14 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor @Getter -public enum TradeOrderItemAfterSaleStatusEnum { +public enum TradeOrderItemAfterSaleStatusEnum implements IntArrayValuable { NONE(0, "未申请"), APPLY(1, "已申请"), SUCCESS(2, "申请成功"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderItemAfterSaleStatusEnum::getStatus).toArray(); + /** * 状态值 */ @@ -29,6 +34,11 @@ public enum TradeOrderItemAfterSaleStatusEnum { // TODO 芋艿:EXPIRED 已失效不允许申请售后 // TODO 芋艿:PART_AFTER_SALE 部分售后 + @Override + public int[] array() { + return ARRAYS; + } + /** * 判断指定状态,是否正处于【未申请】状态 * diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java index 33ddbd662..ad0768493 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.trade.enums.order; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; + /** * 交易订单 - 状态 * @@ -12,7 +15,7 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor @Getter -public enum TradeOrderStatusEnum { +public enum TradeOrderStatusEnum implements IntArrayValuable { UNPAID(0, "未付款"), PAID(10, "已付款"), // 例如说,拼团订单,支付后,需要拼团成功后,才会处于待发货 @@ -23,6 +26,8 @@ public enum TradeOrderStatusEnum { // TODO 芋艿: TAKE("待核验"):虚拟订单需要核验商品 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderStatusEnum::getStatus).toArray(); + /** * 状态值 */ @@ -32,6 +37,11 @@ public enum TradeOrderStatusEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } + /** * 判断指定状态,是否正处于【已取消】状态 * diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java index c10d0065a..c8001b490 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java @@ -1,8 +1,11 @@ package cn.iocoder.yudao.module.trade.enums.order; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; + /** * 交易订单 - 类型 * @@ -10,13 +13,15 @@ import lombok.RequiredArgsConstructor; */ @RequiredArgsConstructor @Getter -public enum TradeOrderTypeEnum { +public enum TradeOrderTypeEnum implements IntArrayValuable { NORMAL(0, "普通订单"), SECKILL(1, "秒杀订单"), TEAM(2, "拼团订单"), BARGAIN(3, "砍价订单"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); + /** * 类型 */ @@ -26,4 +31,9 @@ public enum TradeOrderTypeEnum { */ private final String name; + @Override + public int[] array() { + return ARRAYS; + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java index 945b19496..1d0d604b3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java @@ -1,7 +1,12 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespVO; +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; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -12,6 +17,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @@ -27,6 +33,14 @@ public class TradeAfterSaleController { @Resource private TradeAfterSaleService afterSaleService; + @GetMapping("/page") + @ApiOperation("获得交易售后分页") + @PreAuthorize("@ss.hasPermission('trade:after-sale:query')") + public CommonResult> getAfterSalePage(@Valid TradeAfterSalePageReqVO pageVO) { + PageResult pageResult = afterSaleService.getAfterSalePage(pageVO); + return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult)); + } + @PutMapping("/agree") @ApiOperation("同意售后") @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java new file mode 100644 index 000000000..cd86a0c6a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import cn.iocoder.yudao.module.trade.controller.admin.base.property.ProductPropertyRespVO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 交易售后 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class TradeAfterSaleBaseVO { + + @ApiModelProperty(value = "售后流水号", required = true, example = "202211190847450020500077") + @NotNull(message = "售后流水号不能为空") + private String no; + + @ApiModelProperty(value = "售后状态", required = true, example = "2", notes = "参见 TradeAfterSaleStatusEnum 枚举") + @NotNull(message = "售后状态不能为空") + private Integer status; + + @ApiModelProperty(value = "售后类型", required = true, example = "2", notes = "参见 TradeAfterSaleTypeEnum 枚举") + @NotNull(message = "售后类型不能为空") + private Integer type; + + @ApiModelProperty(value = "用户编号", required = true, example = "30337") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @ApiModelProperty(value = "申请原因", required = true, example = "不喜欢") + @NotNull(message = "申请原因不能为空") + private String applyReason; + + @ApiModelProperty(value = "补充描述", example = "你说的对") + private String applyDescription; + + @ApiModelProperty(value = "补充凭证图片", example = "https://www.iocoder.cn/1.png") + private List applyPicUrls; + + @ApiModelProperty(value = "订单编号", required = true, example = "18078") + @NotNull(message = "订单编号不能为空") + private Long orderId; + + @ApiModelProperty(value = "订单流水号", required = true, example = "2022111917190001") + @NotNull(message = "订单流水号不能为空") + private Long orderNo; + + @ApiModelProperty(value = "订单项编号", required = true, example = "572") + @NotNull(message = "订单项编号不能为空") + private Long orderItemId; + + @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "2888") + @NotNull(message = "商品 SPU 编号不能为空") + private Long spuId; + + @ApiModelProperty(value = "商品 SPU 名称", required = true, example = "李四") + @NotNull(message = "商品 SPU 名称不能为空") + private String spuName; + + @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "15657") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @ApiModelProperty(value = "规格值数组") + private List properties; + + @ApiModelProperty(value = "商品图片", example = "https://www.iocoder.cn/2.png") + private String picUrl; + + @ApiModelProperty(value = "购买数量", required = true, example = "20012") + @NotNull(message = "购买数量不能为空") + private Integer count; + + @ApiModelProperty(value = "审批时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime auditTime; + + @ApiModelProperty(value = "审批人", example = "30835") + private Long auditUserId; + + @ApiModelProperty(value = "审批备注", example = "不香") + private String auditReason; + + @ApiModelProperty(value = "退款金额,单位:分", required = true, example = "18077") + @NotNull(message = "退款金额,单位:分不能为空") + private Integer refundPrice; + + @ApiModelProperty(value = "支付退款编号", example = "10271") + private Long payRefundId; + + @ApiModelProperty(value = "退款时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime refundTime; + + @ApiModelProperty(value = "退货物流公司编号", example = "10") + private Long logisticsId; + + @ApiModelProperty(value = "退货物流单号", example = "610003952009") + private String logisticsNo; + + @ApiModelProperty(value = "退货时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime deliveryTime; + + @ApiModelProperty(value = "收货时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime receiveTime; + + @ApiModelProperty(value = "收货备注", example = "不喜欢") + private String receiveReason; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java new file mode 100644 index 000000000..d21b254b0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 交易售后分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class TradeAfterSalePageReqVO extends PageParam { + + @ApiModelProperty(value = "售后流水号", example = "202211190847450020500077", notes = "模糊匹配") + private String no; + + @ApiModelProperty(value = "售后状态", example = "2", notes = "参见 TradeAfterSaleStatusEnum 枚举") + @InEnum(value = TradeAfterSaleStatusEnum.class, message = "售后状态必须是 {value}") + private Integer status; + + @ApiModelProperty(value = "售后类型", example = "2", notes = "参见 TradeAfterSaleTypeEnum 枚举") + @InEnum(value = TradeAfterSaleTypeEnum.class, message = "售后类型必须是 {value}") + private Integer type; + + @ApiModelProperty(value = "订单编号", example = "18078", notes = "模糊匹配") + private String orderNo; + + @ApiModelProperty(value = "商品 SPU 名称", example = "李四", notes = "模糊匹配") + private String spuName; + + @ApiModelProperty(value = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespVO.java new file mode 100644 index 000000000..c15a1979c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@ApiModel("管理后台 - 交易售后 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class TradeAfterSaleRespVO extends TradeAfterSaleBaseVO { + + @ApiModelProperty(value = "售后编号", required = true, example = "27630") + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java new file mode 100644 index 000000000..0baa83e49 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java @@ -0,0 +1,4 @@ +/** + * 放置该模块通用的 VO 类 + */ +package cn.iocoder.yudao.module.trade.controller.admin.base; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/property/ProductPropertyRespVO.java new file mode 100644 index 000000000..5e43d690d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/property/ProductPropertyRespVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.trade.controller.admin.base.property; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel("管理后台 - 商品规格 Request VO") +@Data +public class ProductPropertyRespVO { + + @ApiModelProperty(value = "属性编号", required = true, example = "1") + private Long propertyId; + + @ApiModelProperty(value = "属性值编号", required = true, example = "2") + private Long valueId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java index afe918d2c..d93eb9b58 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.trade.convert.aftersale; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -32,4 +34,6 @@ public interface TradeAfterSaleConvert { PayRefundCreateReqDTO convert(String userIp, TradeAfterSaleDO afterSale, TradeOrderProperties orderProperties); + PageResult convertPage(PageResult page); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java index 106c8a8d6..6cda2f767 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java @@ -80,6 +80,12 @@ public class TradeAfterSaleDO extends BaseDO { * 关联 {@link TradeOrderDO#getId()} */ private Long orderId; + /** + * 订单流水号 + * + * 冗余 {@link TradeOrderDO#getNo()} + */ + private String orderNo; /** * 交易订单项编号 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java index 25a4bb8df..e05eb0d6c 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -11,6 +11,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; +import java.io.Serializable; import java.util.List; /** @@ -153,7 +154,7 @@ public class TradeOrderItemDO extends BaseDO { * 商品属性 */ @Data - public static class Property { + public static class Property implements Serializable { /** * 属性编号 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java index 4e03a33de..47be712e9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.trade.dal.mysql.aftersale; +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.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -8,6 +11,17 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface TradeAfterSaleMapper extends BaseMapperX { + default PageResult selectPage(TradeAfterSalePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(TradeAfterSaleDO::getNo, reqVO.getNo()) + .eqIfPresent(TradeAfterSaleDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeAfterSaleDO::getType, reqVO.getType()) + .likeIfPresent(TradeAfterSaleDO::getOrderNo, reqVO.getOrderNo()) + .likeIfPresent(TradeAfterSaleDO::getSpuName, reqVO.getSpuName()) + .betweenIfPresent(TradeAfterSaleDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(TradeAfterSaleDO::getId)); + } + default int updateByIdAndStatus(Long id, Integer status, TradeAfterSaleDO update) { return update(update, new LambdaUpdateWrapper() .eq(TradeAfterSaleDO::getId, id).eq(TradeAfterSaleDO::getStatus, status)); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java index 1eff8c94a..262afd45f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.trade.service.aftersale; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; +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.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; /** * 交易售后 Service 接口 @@ -12,6 +15,14 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa */ public interface TradeAfterSaleService { + /** + * 获得交易售后分页 + * + * @param pageReqVO 分页查询 + * @return 交易售后分页 + */ + PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO); + /** * 【会员】创建交易售后 *

diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java index c295ffe36..45434367d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java @@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.trade.service.aftersale; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; 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; +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.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; @@ -52,6 +54,11 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @Resource private TradeOrderProperties tradeOrderProperties; + @Override + public PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO) { + return tradeAfterSaleMapper.selectPage(pageReqVO); + } + @Override @Transactional(rollbackFor = Exception.class) public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java index 239daeec9..c0a511468 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.trade.service.aftersale; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -18,7 +20,10 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.time.LocalDateTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static java.util.Arrays.asList; @@ -84,4 +89,44 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest { assertNull(afterSale.getReceiveReason()); } + @Test + public void testGetAfterSalePage() { + // mock 数据 + TradeAfterSaleDO dbAfterSale = randomPojo(TradeAfterSaleDO.class, o -> { // 等会查询到 + o.setNo("202211190847450020500077"); + o.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); + o.setType(TradeAfterSaleTypeEnum.RETURN_AND_REFUND.getType()); + o.setOrderNo("202211190847450020500011"); + o.setSpuName("芋艿"); + o.setCreateTime(buildTime(2022, 1, 15)); + }); + tradeAfterSaleMapper.insert(dbAfterSale); + // 测试 no 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setNo("202211190847450020500066"))); + // 测试 status 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()))); + // 测试 type 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setType(TradeAfterSaleTypeEnum.REFUND.getType()))); + // 测试 orderNo 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setOrderNo("202211190847450020500022"))); + // 测试 spuName 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setSpuName("土豆"))); + // 测试 createTime 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setCreateTime(buildTime(2022, 1, 20)))); + // 准备参数 + TradeAfterSalePageReqVO reqVO = new TradeAfterSalePageReqVO(); + reqVO.setNo("20221119084745002050007"); + reqVO.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); + reqVO.setType(TradeAfterSaleTypeEnum.RETURN_AND_REFUND.getType()); + reqVO.setOrderNo("20221119084745002050001"); + reqVO.setSpuName("芋"); + reqVO.setCreateTime(new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 1, 16)}); + + // 调用 + PageResult pageResult = tradeAfterSaleService.getAfterSalePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbAfterSale, pageResult.getList().get(0)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql index 8e073c4ea..b4fc69c55 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql @@ -80,6 +80,7 @@ CREATE TABLE IF NOT EXISTS "trade_after_sale" ( "apply_description" varchar, "apply_pic_urls" varchar, "order_id" bigint NOT NULL, + "order_no" varchar NOT NULL, "order_item_id" bigint NOT NULL, "spu_id" bigint NOT NULL, "spu_name" varchar NOT NULL,