添加申请退货

This commit is contained in:
sin 2019-04-26 00:23:29 +08:00
parent cddffabeba
commit 718554bcfa
17 changed files with 436 additions and 78 deletions

View File

@ -13,9 +13,12 @@ import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.application.convert.CartConvert;
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
import cn.iocoder.mall.order.application.convert.OrderReturnConvert;
import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
import cn.iocoder.mall.order.application.po.user.OrderReturnApplyPO;
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import com.alibaba.dubbo.config.annotation.Reference;
@ -38,7 +41,7 @@ import java.util.stream.Collectors;
@RestController
@RequestMapping("users/order")
@Api(description = "用户订单")
public class UsersOrderController {
public class OrderController {
@Reference(validation = "true")
private OrderService orderService;
@ -124,9 +127,11 @@ public class UsersOrderController {
CommonResult<OrderInfoBO> commonResult = orderService.info(userId, orderId);
OrderInfoBO orderInfoBO = commonResult.getData();
if(orderInfoBO != null) {
CommonResult<DataDictBO> dictResult = dataDictService
.getDataDict(DictKeyConstants.ORDER_STATUS, orderInfoBO.getStatus());
orderInfoBO.setStatusText(dictResult.getData().getDisplayName());
}
return commonResult;
}
}

View File

@ -12,6 +12,7 @@ import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@ -49,6 +50,7 @@ public class OrderLogisticsController {
// 获取字典值
Set<Integer> dictValues = logisticsList.stream().map(o -> o.getLogistics()).collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(dictValues)) {
CommonResult<List<DataDictBO>> dictResult = dataDictService
.getDataDictList(DictKeyConstants.ORDER_LOGISTICS_COMPANY, dictValues);
@ -69,6 +71,7 @@ public class OrderLogisticsController {
return o;
}).collect(Collectors.toList());
}
}
return commonResult;
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.mall.order.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.DataDictService;
import cn.iocoder.mall.admin.api.bo.DataDictBO;
import cn.iocoder.mall.order.api.OrderReturnService;
import cn.iocoder.mall.order.api.constant.DictKeyConstants;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.application.convert.OrderReturnConvert;
import cn.iocoder.mall.order.application.po.user.OrderReturnApplyPO;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 订单退款/售后流程
*
* @author Sin
* @time 2019-04-25 22:04
*/
@RestController
@RequestMapping("users/order_return")
public class OrderReturnController {
@Reference(validation = "true")
private OrderReturnService orderReturnService;
@Reference(validation = "true")
private DataDictService dataDictService;
@GetMapping("reason")
@ApiOperation("原因")
public CommonResult<List<DataDictBO>> orderReturnReason() {
return dataDictService.getDataDict(DictKeyConstants.ORDER_RETURN_REASON);
}
@PostMapping("apply")
@ApiOperation("订单售后")
public CommonResult orderReturnApply(@RequestBody OrderReturnApplyPO orderReturnApplyPO) {
OrderReturnApplyDTO applyDTO = OrderReturnConvert.INSTANCE.convert(orderReturnApplyPO);
return orderReturnService.orderReturnApply(applyDTO);
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.mall.order.application.convert;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.application.po.user.OrderReturnApplyPO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
/**
* 订单退货
*
* @author Sin
* @time 2019-04-25 21:54
*/
@Mapper
public interface OrderReturnConvert {
OrderReturnConvert INSTANCE = Mappers.getMapper(OrderReturnConvert.class);
@Mappings({})
OrderReturnApplyDTO convert(OrderReturnApplyPO orderReturnApplyPO);
}

View File

@ -0,0 +1,48 @@
package cn.iocoder.mall.order.application.po.user;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* 订单售后
*
* @author Sin
* @time 2019-04-25 20:59
*/
@Data
@Accessors(chain = true)
public class OrderReturnApplyPO implements Serializable {
/**
* 订单编号
*/
@NotNull(message = "orderId 不能为空!")
private Integer orderId;
/**
* 退款类型
*
* - 1退货退款
* - 2退款
*/
@NotNull(message = "退货类型不能为空!")
private Integer returnType;
/**
* 退货原因(字典值)
*
* {@link cn.iocoder.mall.order.biz.constants.OrderReturnReasonEnum}
*/
@NotNull(message = "必须选择退货原因")
private Integer reason;
/**
* 原因如果选择其他原因保存在这
*
* {@link cn.iocoder.mall.order.biz.constants.OrderReturnReasonEnum#REASON_000}
*/
@Size(max = 200)
private String describe;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.order.api;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnCreateDTO;
/**
@ -11,11 +12,13 @@ import cn.iocoder.mall.order.api.dto.OrderReturnCreateDTO;
*/
public interface OrderReturnService {
/**
* 订单退货 - 创建
* 订单 - 退货
*
* @param orderReturnCreate
* @param orderReturnApplyDTO
* @return
*/
CommonResult createOrderReturn(OrderReturnCreateDTO orderReturnCreate);
CommonResult orderReturnApply(OrderReturnApplyDTO orderReturnApplyDTO);
}

View File

@ -5,6 +5,7 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 订单 info
@ -104,6 +105,64 @@ public class OrderInfoBO implements Serializable {
* 最新物流信息
*/
private LogisticsDetail latestLogisticsDetail;
/**
* 订单 item
*/
private List<OrderItem> orderItems;
@Data
@Accessors(chain = true)
public static class OrderItem {
/**
* 商品编号
*/
private Integer skuId;
/**
* 商品名称
*/
private String skuName;
/**
* 商品图片
*/
private String skuImage;
/**
* 数量
*/
private Integer quantity;
/**
* 原始单价单位
*/
private Integer originPrice;
/**
* 购买单价单位
*/
private Integer buyPrice;
/**
* 最终价格单位
*/
private Integer presentPrice;
/**
* 购买总金额单位
*
* 用途类似 {@link #presentTotal}
*/
private Integer buyTotal;
/**
* 优惠总金额单位
*/
private Integer discountTotal;
/**
* 最终总金额单位
*
* 注意presentPrice * quantity 不一定等于 presentTotal
* 因为存在无法整除的情况
* 举个例子presentPrice = 8.33 quantity = 3 的情况presentTotal 有可能是 24.99 也可能是 25
* 所以需要存储一个该字段
*/
private Integer presentTotal;
}
@Data
@Accessors(chain = true)

View File

@ -16,4 +16,8 @@ public class DictKeyConstants {
* 订单 - 物流商家
*/
public static final String ORDER_LOGISTICS_COMPANY = "logistics_company";
/**
* 订单 - 退货原因
*/
public static final String ORDER_RETURN_REASON = "order_return_reason";
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.mall.order.api.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @author Sin
* @time 2019-04-25 21:06
*/
@Data
@Accessors(chain = true)
public class OrderReturnApplyDTO implements Serializable {
/**
* 订单编号
*/
private Integer orderId;
/**
* 退货原因(字典值)
*/
private Integer reason;
/**
* 问题描述
*/
private String describe;
/**
* 退款类型
*
* - 1退货退款
* - 2退款
*/
private Integer returnType;
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.bo.OrderInfoBO;
import cn.iocoder.mall.order.api.bo.OrderItemBO;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderItemUpdateDTO;
@ -32,4 +33,7 @@ public interface OrderItemConvert {
@Mappings({})
List<OrderItemBO> convertOrderItemDO(List<OrderItemDO> orderItemDOList);
@Mappings({})
List<OrderInfoBO.OrderItem> convertOrderInfoWithOrderItem(List<OrderItemDO> orderItemDOList);
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnCreateDTO;
import cn.iocoder.mall.order.biz.dataobject.OrderReturnDO;
import org.mapstruct.Mapper;
@ -20,4 +20,7 @@ public interface OrderReturnConvert {
@Mappings({})
OrderReturnDO convert(OrderReturnCreateDTO orderReturnCreate);
@Mappings({})
OrderReturnDO convert(OrderReturnApplyDTO orderReturnApplyDTO);
}

View File

@ -1,5 +1,7 @@
package cn.iocoder.mall.order.biz.dao;
import cn.iocoder.mall.order.biz.dataobject.OrderReturnDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
/**
@ -10,4 +12,30 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public interface OrderReturnMapper {
/**
* 插入 - 退货信息
*
* @param orderReturnDO
* @return
*/
int insert(OrderReturnDO orderReturnDO);
/**
* 更新 - 根据 orderId
*
* @param orderReturnDO
* @return
*/
int updateByOrderId(OrderReturnDO orderReturnDO);
/**
* 查询 - 根据 orderId
*
* @param orderId
* @return
*/
OrderReturnDO selectByOrderId(
@Param("orderId") Integer orderId
);
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.mall.order.biz.dataobject;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
@ -14,7 +15,7 @@ import java.util.Date;
*/
@Data
@Accessors(chain = true)
public class OrderReturnDO extends DeletableDO {
public class OrderReturnDO extends BaseDO {
/**
* 编号自动增长
@ -28,22 +29,6 @@ public class OrderReturnDO extends DeletableDO {
* 订单号 保存一个冗余
*/
private String orderNo;
/**
* 订单 item 编号
*/
private Integer orderItemId;
/**
* 商品编号保存一个冗余如果一个订单下存在多个商品会有很大的作用
*/
private Integer skuId;
/**
* 商品名称
*/
private String skuName;
/**
* 商品图片
*/
private String skuImage;
/**
* 物流id
*/
@ -57,21 +42,15 @@ public class OrderReturnDO extends DeletableDO {
*
* {@link cn.iocoder.mall.order.biz.constants.OrderReturnReasonEnum}
*/
private Integer orderReason;
private Integer reason;
/**
* 原因如果选择其他原因保存在这
*
* {@link cn.iocoder.mall.order.biz.constants.OrderReturnReasonEnum#REASON_000}
* 问题描述
*/
private String otherReasons;
private String describe;
///
/// 时间信息
/**
* 创建时间
*/
private Date createTime;
/**
* 同意时间
*/
@ -88,17 +67,13 @@ public class OrderReturnDO extends DeletableDO {
* 成交时间确认时间
*/
private Date closingTime;
///
/// 其他
/**
* 订单类型
* 退款类型
*
* - 0 Order 订单 对整个订单退货
* - 1 OrderItem 订单 对订单某一个商品退货
* - 1退货退款
* - 2退款
*/
private Integer orderType;
private Integer returnType;
/**
* 状态
*
@ -109,5 +84,4 @@ public class OrderReturnDO extends DeletableDO {
* - 5退货成功
*/
private Integer status;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.order.biz.service;
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
import cn.iocoder.common.framework.util.CollectionUtil;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
@ -20,10 +21,9 @@ import cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDetailDO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -67,10 +67,12 @@ public class OrderLogisticsServiceImpl implements OrderLogisticsService {
.map(o -> o.getOrderLogisticsId())
.collect(Collectors.toSet());
List<OrderLogisticsDO> orderLogisticsDOList = orderLogisticsMapper.selectByIds(orderLogisticsIds);
List<OrderLogisticsDetailDO> orderLogisticsDetailDOList
= orderLogisticsDetailMapper.selectByOrderLogisticsIds(orderLogisticsIds);
List<OrderLogisticsDO> orderLogisticsDOList = Collections.emptyList();
List<OrderLogisticsDetailDO> orderLogisticsDetailDOList = Collections.emptyList();
if (!CollectionUtils.isEmpty(orderLogisticsIds)) {
orderLogisticsDOList = orderLogisticsMapper.selectByIds(orderLogisticsIds);
orderLogisticsDetailDOList = orderLogisticsDetailMapper.selectByOrderLogisticsIds(orderLogisticsIds);
}
// 转换 return 的数据
List<OrderLogisticsInfoBO.Logistics> logistics

View File

@ -1,11 +1,15 @@
package cn.iocoder.mall.order.biz.service;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.OrderReturnService;
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.api.constant.OrderReturnStatusEnum;
import cn.iocoder.mall.order.api.dto.OrderReturnCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.biz.convert.OrderReturnConvert;
import cn.iocoder.mall.order.biz.dao.OrderMapper;
import cn.iocoder.mall.order.biz.dao.OrderReturnMapper;
import cn.iocoder.mall.order.biz.dataobject.OrderDO;
import cn.iocoder.mall.order.biz.dataobject.OrderReturnDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -22,19 +26,30 @@ import java.util.Date;
@com.alibaba.dubbo.config.annotation.Service(validation = "true")
public class OrderReturnServiceImpl implements OrderReturnService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderReturnMapper orderReturnMapper;
@Override
public CommonResult createOrderReturn(OrderReturnCreateDTO orderReturnCreate) {
public CommonResult orderReturnApply(OrderReturnApplyDTO orderReturnDTO) {
OrderDO checkOrder = orderMapper.selectById(orderReturnDTO.getOrderId());
// 检查订单是否 存在
if (checkOrder == null) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
}
OrderReturnDO orderReturnDO = OrderReturnConvert.INSTANCE.convert(orderReturnCreate);
// 转换 DO
OrderReturnDO orderReturnDO = OrderReturnConvert.INSTANCE.convert(orderReturnDTO);
orderReturnDO
.setCreateTime(new Date())
.setStatus(OrderReturnStatusEnum.RETURN_APPLICATION.getValue());
.setOrderId(checkOrder.getId())
.setOrderNo(checkOrder.getOrderNo())
.setStatus(OrderReturnStatusEnum.RETURN_APPLICATION.getValue())
.setCreateTime(new Date());
return null;
// 保存申请信息
orderReturnMapper.insert(orderReturnDO);
return CommonResult.success(null);
}
}

View File

@ -6,10 +6,7 @@ import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.OrderService;
import cn.iocoder.mall.order.api.bo.*;
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.api.constant.OrderHasReturnExchangeEnum;
import cn.iocoder.mall.order.api.constant.OrderStatusEnum;
import cn.iocoder.mall.order.api.constant.PayAppId;
import cn.iocoder.mall.order.api.constant.*;
import cn.iocoder.mall.order.api.dto.*;
import cn.iocoder.mall.order.biz.constants.OrderDeliveryTypeEnum;
import cn.iocoder.mall.order.biz.constants.OrderRecipientTypeEnum;
@ -61,6 +58,8 @@ public class OrderServiceImpl implements OrderService {
private OrderRecipientMapper orderRecipientMapper;
@Autowired
private OrderCancelMapper orderCancelMapper;
@Autowired
private OrderReturnMapper orderReturnMapper;
@Reference
private ProductSpuService productSpuService;
@ -165,11 +164,16 @@ public class OrderServiceImpl implements OrderService {
List<OrderItemDO> itemDOList = orderItemMapper
.selectByDeletedAndOrderId(orderId, DeletedStatusEnum.DELETED_NO.getValue());
List<OrderInfoBO.OrderItem> orderItems
= OrderItemConvert.INSTANCE.convertOrderInfoWithOrderItem(itemDOList);
Set<Integer> orderLogisticsIds = itemDOList.stream()
.filter(o -> o.getOrderLogisticsId() != null)
.map(o -> o.getOrderLogisticsId())
.collect(Collectors.toSet());
// 收件人信息
OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderId);
@ -186,6 +190,7 @@ public class OrderServiceImpl implements OrderService {
OrderInfoBO.Recipient recipient = OrderRecipientConvert.INSTANCE.convertOrderInfoRecipient(orderRecipientDO);
OrderInfoBO orderInfoBO = OrderConvert.INSTANCE.convert(orderDO);
orderInfoBO.setRecipient(recipient);
orderInfoBO.setOrderItems(orderItems);
orderInfoBO.setLatestLogisticsDetail(logisticsDetail);
return CommonResult.success(orderInfoBO);
}

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.order.biz.dao.OrderReturnMapper">
<sql id="FIELDS">
id,
order_id,
order_no,
order_logistics_id,
reason,
`describe`,
approval_time,
logistics_time,
receiver_time,
closing_time,
return_type,
status,
create_time,
update_time
</sql>
<!--
插入数据
-->
<insert id="insert" parameterType="OrderReturnDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO `order_return` (
order_id, order_no, order_logistics_id,
reason, `describe`,
approval_time, logistics_time, receiver_time, closing_time,
return_type, status,
create_time, update_time)
VALUES (
#{orderId}, #{orderNo}, #{orderLogisticsId},
#{reason}, #{describe},
#{approvalTime}, #{logisticsTime}, #{receiverTime}, #{closingTime},
#{returnType}, #{status}, #{createTime}, #{updateTime})
</insert>
<!--
更新 - 可更新的字段
-->
<sql id="updateFieldSql">
<set>
<if test="orderLogisticsId != null">
, order_logistics_id = #{orderLogisticsId}
</if>
<if test="reason != null">
, reason = #{reason}
</if>
<if test="describe != null">
, `describe` = #{describe}
</if>
<if test="approvalTime != null">
, approval_time = #{approvalTime}
</if>
<if test="logisticsTime != null">
, logistics_time = #{logisticsTime}
</if>
<if test="receiverTime != null">
, receiver_time = #{receiverTime}
</if>
<if test="deliveryTime != null">
, delivery_time = #{deliveryTime}
</if>
<if test="closingTime != null">
, closing_time = #{closingTime}
</if>
<if test="returnType != null">
, return_type = #{returnType}
</if>
<if test="status != null">
, status = #{status}
</if>
<if test="createTime != null">
, create_time = #{createTime}
</if>
<if test="updateTime != null">
, update_time = #{updateTime}
</if>
</set>
</sql>
<!--
更新 - 根据 id 更新
-->
<update id="updateByOrderId" parameterType="OrderReturnDO">
UPDATE `order_return`
<include refid="updateFieldSql"/>
WHERE order_id = #{orderId}
</update>
<!--
查询 - 根据id 查询
-->
<select id="selectByOrderId" resultType="cn.iocoder.mall.order.biz.dataobject.OrderReturnDO">
SELECT
<include refid="FIELDS"/>
FROM `order_return`
WHERE id = #{id}
</select>
</mapper>