diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java new file mode 100644 index 0000000..06865a7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderRefundStatus.java @@ -0,0 +1,31 @@ +package com.ruoyi.common.enums; + +/** + * 用户状态 + * + * @author ruoyi + */ +public enum OrderRefundStatus +{ + NO_REFUND(1, "无售后"), + APPLY(2, "申请中"), + WAIT(3, "退款中"), + SUCCESS(4, "退款成功"), + FAIL(5,"退款失败"); + + private final Integer type; + private final String msg; + + private OrderRefundStatus(Integer type, String msg) { + this.type = type; + this.msg = msg; + } + + public Integer getType() { + return this.type; + } + + public String getMsg() { + return this.msg; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 536cb3c..855bc00 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -3,6 +3,8 @@ package com.ruoyi.common.utils; import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.Date; import org.apache.commons.lang3.time.DateFormatUtils; @@ -152,4 +154,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils // long sec = diff % nd % nh % nm / ns; return day + "天" + hour + "小时" + min + "分钟"; } + + /** + * 获取2个时间间隔天数 + * @param beginTime + * @param endTime + * @return + */ + public static Long betweenDay(LocalDateTime beginTime, LocalDateTime endTime){ + return ChronoUnit.DAYS.between(beginTime.toLocalDate().atStartOfDay(),endTime.toLocalDate().atStartOfDay()); + } } diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/ApplyRefundDTO.java b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/ApplyRefundDTO.java index c7f084f..100fc30 100644 --- a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/ApplyRefundDTO.java +++ b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/dto/ApplyRefundDTO.java @@ -22,7 +22,7 @@ public class ApplyRefundDTO { @ApiModelProperty(value = "申请退货数量", required = true) private Integer quantity; - @ApiModelProperty(value = "退款金额", required = true) + @ApiModelProperty(value = "退款金额") private BigDecimal refundAmount; @ApiModelProperty(value = "描述") diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java index 1876b1a..169a427 100644 --- a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java +++ b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java @@ -1,6 +1,7 @@ package com.cyl.h5.service; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -16,14 +17,8 @@ import com.cyl.h5.pojo.vo.H5OrderVO; import com.cyl.h5.pojo.vo.OrderCalcVO; import com.cyl.h5.pojo.vo.SkuViewDTO; import com.cyl.h5.pojo.vo.form.OrderSubmitForm; -import com.cyl.manager.oms.domain.Order; -import com.cyl.manager.oms.domain.OrderItem; -import com.cyl.manager.oms.domain.OrderOperateHistory; -import com.cyl.manager.oms.domain.WechatPaymentHistory; -import com.cyl.manager.oms.mapper.OrderItemMapper; -import com.cyl.manager.oms.mapper.OrderMapper; -import com.cyl.manager.oms.mapper.OrderOperateHistoryMapper; -import com.cyl.manager.oms.mapper.WechatPaymentHistoryMapper; +import com.cyl.manager.oms.domain.*; +import com.cyl.manager.oms.mapper.*; import com.cyl.manager.oms.service.OrderItemService; import com.cyl.manager.oms.service.OrderOperateHistoryService; import com.cyl.manager.pms.domain.Product; @@ -44,8 +39,10 @@ import com.github.pagehelper.PageHelper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisService; +import com.ruoyi.common.enums.OrderRefundStatus; import com.ruoyi.common.enums.OrderStatus; import com.ruoyi.common.enums.TradeStatusEnum; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.IDGenerator; import com.ruoyi.framework.config.LocalDataUtil; import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; @@ -115,6 +112,9 @@ public class H5OrderService { @Autowired private RedisService redisService; + @Autowired + private AftersaleMapper aftersaleMapper; + @Transactional public Long submit(OrderSubmitForm form) { Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO); @@ -586,8 +586,102 @@ public class H5OrderService { * @param applyRefundDTO * @return */ + @Transactional public String applyRefund(ApplyRefundDTO applyRefundDTO) { + Order order = orderMapper.selectById(applyRefundDTO.getOrderId()); + //是否符合售后条件 + this.checkIfCanApplyRefund(order); + LocalDateTime optDate = LocalDateTime.now(); + Long memberId = order.getMemberId(); + //创建售后单aftersale + Aftersale addAftersale = new Aftersale(); + addAftersale.setId(IDGenerator.generateId()); + addAftersale.setMemberId(order.getMemberId()); + addAftersale.setOrderId(order.getId()); + addAftersale.setReturnAmount(order.getPayAmount()); + addAftersale.setType(applyRefundDTO.getApplyRefundType()); + addAftersale.setStatus(OrderRefundStatus.APPLY.getType()); + addAftersale.setReason(applyRefundDTO.getReason()); + addAftersale.setQuantity(applyRefundDTO.getQuantity()); + addAftersale.setReason(applyRefundDTO.getReason()); + addAftersale.setDescription(applyRefundDTO.getDescription()); + addAftersale.setProofPics(applyRefundDTO.getProofPics()); + addAftersale.setCreateTime(optDate); + addAftersale.setCreateBy(memberId); + addAftersale.setUpdateTime(optDate); + addAftersale.setUpdateBy(memberId); + int rows = aftersaleMapper.insert(addAftersale); + if (rows != 1) { + throw new RuntimeException("插入订单售后失败"); + } + //创建aftersale item + QueryWrapper orderItemQw = new QueryWrapper<>(); + orderItemQw.eq("order_id", order.getId()); + List orderItemList = orderItemMapper.selectList(orderItemQw); + List addAftersaleItemList = new ArrayList<>(); + orderItemList.forEach(orderItem -> { + AftersaleItem aftersaleItem = new AftersaleItem(); + aftersaleItem.setMemberId(memberId); + aftersaleItem.setOrderId(orderItem.getOrderId()); + aftersaleItem.setOrderItemId(orderItem.getId()); + aftersaleItem.setReturnAmount(orderItem.getSalePrice().multiply(BigDecimal.valueOf(orderItem.getQuantity()))); + aftersaleItem.setQuantity(orderItem.getQuantity()); + aftersaleItem.setCreateTime(optDate); + aftersaleItem.setCreateBy(memberId); + aftersaleItem.setUpdateTime(optDate); + aftersaleItem.setUpdateBy(memberId); + addAftersaleItemList.add(aftersaleItem); + }); + rows = aftersaleMapper.insertBatch(addAftersaleItemList); + if (rows < 1){ + throw new RuntimeException("创建售后订单item失败"); + } + //更新订单 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", order.getId()).set("aftersale_status", OrderRefundStatus.APPLY.getType()) + .set("update_time", optDate) + .set("update_by", memberId); + rows = orderMapper.update(null, updateWrapper); + if (rows < 1){ + throw new RuntimeException("修改订单状态失败"); + } + //创建订单操作记录 + OrderOperateHistory optHistory = new OrderOperateHistory(); + optHistory.setOrderId(order.getId()); + optHistory.setOperateMan("用户"); + optHistory.setOrderStatus(11); + optHistory.setCreateTime(optDate); + optHistory.setCreateBy(memberId); + optHistory.setUpdateBy(memberId); + optHistory.setUpdateTime(optDate); + rows = orderOperateHistoryMapper.insert(optHistory); + if (rows < 1){ + throw new RuntimeException("创建订单操作记录失败"); + } + return "售后申请成功"; + } - return null; + /** + * check是否能售后 可售后的状态为:待发货、待收货、已完成 + * @param order 订单 + */ + private void checkIfCanApplyRefund(Order order){ + if (order == null){ + throw new RuntimeException("为查询到订单信息"); + } + Integer status = order.getStatus(); + boolean flag = OrderStatus.NOT_DELIVERED.getType().equals(status) || OrderStatus.DELIVERED.getType().equals(status) + || OrderStatus.COMPLETE.getType().equals(status); + if (!flag){ + throw new RuntimeException("该订单无法申请售后"); + } + if (OrderStatus.COMPLETE.getType().equals(order.getStatus()) && + DateUtils.betweenDay(LocalDateTime.now(), order.getReceiveTime()) > 7){ + throw new RuntimeException("订单确认收货时间已超过7天,无法申请售后"); + } + if(OrderRefundStatus.APPLY.getType().equals(order.getAftersaleStatus()) + || OrderRefundStatus.WAIT.getType().equals(order.getAftersaleStatus())){ + throw new RuntimeException("售后正在处理中"); + } } } diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/oms/domain/Aftersale.java b/ruoyi-mall/src/main/java/com/cyl/manager/oms/domain/Aftersale.java index f506de9..ff88449 100644 --- a/ruoyi-mall/src/main/java/com/cyl/manager/oms/domain/Aftersale.java +++ b/ruoyi-mall/src/main/java/com/cyl/manager/oms/domain/Aftersale.java @@ -2,6 +2,9 @@ package com.cyl.manager.oms.domain; import java.math.BigDecimal; import java.time.LocalDateTime; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.ruoyi.common.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -20,6 +23,7 @@ public class Aftersale extends BaseAudit { private static final long serialVersionUID = 1L; @ApiModelProperty("ID") + @TableId(type = IdType.ASSIGN_ID) private Long id; @ApiModelProperty("MEMBER_ID") diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/oms/mapper/AftersaleMapper.java b/ruoyi-mall/src/main/java/com/cyl/manager/oms/mapper/AftersaleMapper.java index 0c2e9d2..e510771 100644 --- a/ruoyi-mall/src/main/java/com/cyl/manager/oms/mapper/AftersaleMapper.java +++ b/ruoyi-mall/src/main/java/com/cyl/manager/oms/mapper/AftersaleMapper.java @@ -3,6 +3,8 @@ package com.cyl.manager.oms.mapper; import java.util.List; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.cyl.manager.oms.domain.Aftersale; +import com.cyl.manager.oms.domain.AftersaleItem; +import org.apache.ibatis.annotations.Param; /** * 订单售后Mapper接口 @@ -17,4 +19,6 @@ public interface AftersaleMapper extends BaseMapper { * @return 订单售后集合 */ List selectByEntity(Aftersale aftersale); + + Integer insertBatch(@Param("list") List list); } diff --git a/ruoyi-mall/src/main/resources/mapper/oms/AftersaleMapper.xml b/ruoyi-mall/src/main/resources/mapper/oms/AftersaleMapper.xml index 0ae4417..964f582 100644 --- a/ruoyi-mall/src/main/resources/mapper/oms/AftersaleMapper.xml +++ b/ruoyi-mall/src/main/resources/mapper/oms/AftersaleMapper.xml @@ -31,6 +31,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select id, member_id, order_id, return_amount, type, status, handle_time, quantity, reason, description, proof_pics, handle_note, handle_man, create_by, create_time, update_by, update_time from oms_aftersale + + insert into oms_aftersale_item + (member_id,order_id,order_item_id,return_amount,quantity,create_by,create_time,update_by,update_time) + values + + + #{item.memberId,jdbcType=BIGINT}, + #{item.orderId,jdbcType=BIGINT}, + #{item.orderItemId,jdbcType=BIGINT}, + #{item.returnAmount,jdbcType=DECIMAL}, + #{item.quantity,jdbcType=BIGINT}, + #{item.createBy,jdbcType=BIGINT}, + #{item.createTime,jdbcType=DATE}, + #{item.updateBy,jdbcType=BIGINT}, + #{item.updateTime,jdbcType=DATE} + + +