- 添加确认订单

- 添加查看物流
This commit is contained in:
sin 2019-04-12 23:00:45 +08:00
parent 209725a25b
commit fa5ea5dfd9
17 changed files with 465 additions and 28 deletions

View File

@ -0,0 +1,35 @@
package cn.iocoder.mall.order.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.OrderLogisticsService;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 订单物流 controller
*
* @author Sin
* @time 2019-04-12 22:24
*/
@RestController
@RequestMapping("users/order_logistics")
@Api(description = "订单物流信息")
public class OrderLogisticsController {
@Autowired
private OrderLogisticsService orderLogisticsService;
@GetMapping("logistics_info")
@ApiOperation("物流详细 - 返回订单所关联的所有物流信息")
public CommonResult<OrderLogisticsInfoBO> logisticsInfo(@RequestParam("orderId") Integer orderId) {
Integer userId = UserSecurityContextHolder.getContext().getUserId();
return orderLogisticsService.logisticsInfo(userId, orderId);
}
}

View File

@ -15,6 +15,7 @@ import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -28,6 +29,7 @@ import java.util.Collections;
*/
@RestController
@RequestMapping("users/order")
@Api(description = "用户订单")
public class UsersOrderController {
@Reference(validation = "true")
@ -50,7 +52,7 @@ public class UsersOrderController {
return orderService.createOrder(orderCreateDTO);
}
@GetMapping("/confirm_create_order")
@GetMapping("confirm_create_order")
public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder(@RequestParam("skuId") Integer skuId,
@RequestParam("quantity") Integer quantity) {
// 创建 CalcOrderPriceDTO 对象并执行价格计算
@ -64,4 +66,10 @@ public class UsersOrderController {
return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData()));
}
@PostMapping("confirm_receiving")
public CommonResult confirmReceiving(@RequestParam("orderId") Integer orderId) {
Integer userId = UserSecurityContextHolder.getContext().getUserId();
return orderService.confirmReceiving(userId, orderId);
}
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.order.api;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.bo.OrderLogisticsBO;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import java.util.List;
/**
* 订单物流信息
*
* @author Sin
* @time 2019-04-12 21:29
*/
public interface OrderLogisticsService {
/**
* 物流信息
*
* @param userId
* @param orderId
* @return
*/
CommonResult<OrderLogisticsInfoBO> logisticsInfo(Integer userId, Integer orderId);
}

View File

@ -97,6 +97,15 @@ public interface OrderService {
*/
CommonResult deleteOrderItem(OrderItemDeletedDTO orderItemDeletedDTO);
/**
* 用户确认订单
*
* @param userId
* @param orderId
* @return
*/
CommonResult confirmReceiving(Integer userId, Integer orderId);
/**
* 更新订单 - 收件这信息
*

View File

@ -0,0 +1,96 @@
package cn.iocoder.mall.order.api.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 订单物流 - 详细信息
*
* @author Sin
* @time 2019-04-12 22:03
*/
@Data
@Accessors(chain = true)
public class OrderLogisticsInfoBO implements Serializable {
/**
* 订单id
*/
private Integer orderId;
/**
* 订单编号
*/
private String orderNo;
/**
* 物流信息
*/
private List<Logistics> logistics;
@Data
@Accessors(chain = true)
public static class Logistics {
/**
* id
*/
private Integer id;
/**
* 收件区域编号
*/
private String areaNo;
/**
* 收件人名称
*/
private String name;
/**
* 收件手机号
*/
private String mobile;
/**
* 收件详细地址
*/
private String address;
/**
* 物流 (字典)
*/
private Integer logistics;
/**
* 物流编号
*/
private String logisticsNo;
///
/// 物流信息
private List<LogisticsDetail> details;
}
@Data
@Accessors(chain = true)
public static class LogisticsDetail {
/**
* id
*/
private Integer id;
/**
* 物流id
*/
private Integer orderLogisticsId;
/**
* 物流时间
*/
private Date logisticsTime;
/**
* 物流时间 text
*/
private String logisticsTimeText;
/**
* 物流信息
*/
private String logisticsInformation;
}
}

View File

@ -22,6 +22,8 @@ public enum OrderErrorCodeEnum {
ORDER_GET_GOODS_INFO_INCORRECT(1008000008, "获取额商品信息不正确!"),
ORDER_GET_USER_ADDRESS_FAIL(1008000009, "获取用户地址失败!"),
ORDER_GET_PAY_FAIL(1008000010, "调用pay失败!"),
ORDER_NOT_USER_ORDER(1008000011, "不是该用户的订单!"),
ORDER_UNABLE_CONFIRM_ORDER(1008000012, "状态不对不能确认订单!"),
// order item
ORDER_ITEM_ONLY_ONE(1008000200, "订单Item只有一个!"),

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.bo.OrderLogisticsBO;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderDeliveryDTO;
import cn.iocoder.mall.order.api.dto.OrderLogisticsUpdateDTO;
@ -33,5 +34,5 @@ public interface OrderLogisticsConvert {
OrderLogisticsDO convert(OrderRecipientDO orderRecipientDO);
@Mappings({})
List<OrderLogisticsBO> convertOrderLogisticsBO(List<OrderLogisticsDO> orderLogisticsDOList);
List<OrderLogisticsInfoBO.Logistics> convertLogistics(List<OrderLogisticsDO> orderLogisticsDOList);
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDetailDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 订单物流 convert
*
* @author Sin
* @time 2019-03-23 14:39
*/
@Mapper
public interface OrderLogisticsDetailConvert {
OrderLogisticsDetailConvert INSTANCE = Mappers.getMapper(OrderLogisticsDetailConvert.class);
@Mappings({})
List<OrderLogisticsInfoBO.LogisticsDetail> convertLogisticsDetail(List<OrderLogisticsDetailDO> orderLogisticsDOList);
}

View File

@ -33,9 +33,13 @@ public interface OrderItemMapper {
/**
* 更新 - 根据 orderId
* @param orderId
* @param orderItemDO
*/
void updateByOrderId(@Param("orderItemDO") OrderItemDO orderItemDO);
void updateByOrderId(
@Param("orderId") Integer orderId,
@Param("orderItemDO") OrderItemDO orderItemDO
);
/**
* 更新 - 根据Ids
@ -63,7 +67,7 @@ public interface OrderItemMapper {
* @param deleted
* @return
*/
List<OrderItemDO> selectByOrderIdsAndDeleted(
List<OrderItemDO> selectByDeletedAndOrderIds(
@Param("orderIds") Collection<Integer> orderIds,
@Param("deleted") Integer deleted
);
@ -74,7 +78,7 @@ public interface OrderItemMapper {
* @param orderId
* @return
*/
List<OrderItemDO> selectByOrderIdAndDeleted(
List<OrderItemDO> selectByDeletedAndOrderId(
@Param("orderId") Integer orderId,
@Param("deleted") @NotNull Integer deleted
);

View File

@ -0,0 +1,46 @@
package cn.iocoder.mall.order.biz.dao;
import cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDetailDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
/**
* 订单物流 - 物流详细信息
*
* @author Sin
* @time 2019-04-12 21:35
*/
@Repository
public interface OrderLogisticsDetailMapper {
/**
* 插入
*
* @param orderLogisticsDetailDO
* @return
*/
int insert(OrderLogisticsDetailDO orderLogisticsDetailDO);
/**
* 查询 - 根据 物流id
*
* @param orderLogisticsId
* @return
*/
List<OrderLogisticsDetailDO> selectByOrderLogisticsId(
@Param("orderLogisticsId") Integer orderLogisticsId
);
/**
* 查询 - 根据 物流ids
*
* @param orderLogisticsIds
* @return
*/
List<OrderLogisticsDetailDO> selectByOrderLogisticsIds(
@Param("orderLogisticsIds") Collection<Integer> orderLogisticsIds
);
}

View File

@ -31,7 +31,7 @@ public interface OrderLogisticsMapper {
void updateById(OrderLogisticsDO orderLogisticsDO);
/**
* 查询 - 根据 orderId
* 查询 - 根据 ids
*
* @param ids
* @return
@ -39,4 +39,5 @@ public interface OrderLogisticsMapper {
List<OrderLogisticsDO> selectByIds(
@Param("ids") Collection<Integer> ids
);
}

View File

@ -18,10 +18,6 @@ public class OrderLogisticsDO extends BaseDO {
* id
*/
private Integer id;
/**
* 订单编号
*/
private Integer orderId;
/**
* 收件区域编号
*/

View File

@ -0,0 +1,111 @@
package cn.iocoder.mall.order.biz.service;
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.OrderLogisticsService;
import cn.iocoder.mall.order.api.bo.OrderLogisticsBO;
import cn.iocoder.mall.order.api.bo.OrderLogisticsInfoBO;
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.biz.convert.OrderLogisticsConvert;
import cn.iocoder.mall.order.biz.convert.OrderLogisticsDetailConvert;
import cn.iocoder.mall.order.biz.dao.OrderItemMapper;
import cn.iocoder.mall.order.biz.dao.OrderLogisticsDetailMapper;
import cn.iocoder.mall.order.biz.dao.OrderLogisticsMapper;
import cn.iocoder.mall.order.biz.dao.OrderMapper;
import cn.iocoder.mall.order.biz.dataobject.OrderDO;
import cn.iocoder.mall.order.biz.dataobject.OrderItemDO;
import cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDO;
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 java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 订单物流
*
* @author Sin
* @time 2019-04-12 21:32
*/
@Service
public class OrderLogisticsServiceImpl implements OrderLogisticsService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private OrderLogisticsMapper orderLogisticsMapper;
@Autowired
private OrderLogisticsDetailMapper orderLogisticsDetailMapper;
@Override
public CommonResult<OrderLogisticsInfoBO> logisticsInfo(Integer userId, Integer orderId) {
OrderDO orderDO = orderMapper.selectById(orderId);
if (orderDO == null) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode());
}
if (!userId.equals(orderDO.getUserId())) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_USER_ORDER.getCode());
}
// 获取订单所发货的订单 id
List<OrderItemDO> orderItemDOList = orderItemMapper.selectByDeletedAndOrderId(
orderId, DeletedStatusEnum.DELETED_NO.getValue());
// 获取物流 信息
Set<Integer> orderLogisticsIds = orderItemDOList.stream()
.map(o -> o.getOrderLogisticsId()).collect(Collectors.toSet());
List<OrderLogisticsDO> orderLogisticsDOList = orderLogisticsMapper.selectByIds(orderLogisticsIds);
List<OrderLogisticsDetailDO> orderLogisticsDetailDOList
= orderLogisticsDetailMapper.selectByOrderLogisticsIds(orderLogisticsIds);
// 转换 return 的数据
List<OrderLogisticsInfoBO.Logistics> logistics
= OrderLogisticsConvert.INSTANCE.convertLogistics(orderLogisticsDOList);
List<OrderLogisticsInfoBO.LogisticsDetail> logisticsDetails
= OrderLogisticsDetailConvert.INSTANCE.convertLogisticsDetail(orderLogisticsDetailDOList);
logisticsDetails.stream().map(o -> {
o.setLogisticsTimeText(DateUtil.format(o.getLogisticsTime(), "yyyy-MM-dd HH:mm"));
return o;
}).collect(Collectors.toList());
Map<Integer, List<OrderLogisticsInfoBO.LogisticsDetail>> logisticsDetailMultimap
= logisticsDetails.stream().collect(
Collectors.toMap(
o -> o.getOrderLogisticsId(),
item -> Lists.newArrayList(item),
(oldVal, newVal) -> {
oldVal.addAll(newVal);
return oldVal;
}
)
);
logistics.stream().map(o -> {
if (logisticsDetailMultimap.containsKey(o.getId())) {
o.setDetails(logisticsDetailMultimap.get(o.getId()));
}
return o;
}).collect(Collectors.toList());
return CommonResult.success(
new OrderLogisticsInfoBO()
.setOrderId(orderId)
.setOrderNo(orderDO.getOrderNo())
.setLogistics(logistics)
);
}
}

View File

@ -96,7 +96,7 @@ public class OrderServiceImpl implements OrderService {
// 获取 订单的 items
List<OrderItemDO> orderItemDOList = orderItemMapper
.selectByOrderIdsAndDeleted(orderIds, DeletedStatusEnum.DELETED_NO.getValue());
.selectByDeletedAndOrderIds(orderIds, DeletedStatusEnum.DELETED_NO.getValue());
List<OrderItemBO> orderItemBOList = OrderItemConvert.INSTANCE.convertOrderItemDO(orderItemDOList);
Map<Integer, List<OrderItemBO>> orderItemBOMultimap = orderItemBOList.stream().collect(
@ -135,7 +135,7 @@ public class OrderServiceImpl implements OrderService {
}
List<OrderItemDO> orderItemDOList = orderItemMapper
.selectByOrderIdAndDeleted(orderId, DeletedStatusEnum.DELETED_NO.getValue());
.selectByDeletedAndOrderId(orderId, DeletedStatusEnum.DELETED_NO.getValue());
List<OrderItemBO> orderItemBOList = OrderItemConvert.INSTANCE.convertOrderItemBO(orderItemDOList);
return CommonResult.success(orderItemBOList);
@ -310,7 +310,7 @@ public class OrderServiceImpl implements OrderService {
orderItemMapper.updateById(new OrderItemDO().setId(orderItemId).setPayAmount(payAmount));
// 再重新计算订单金额
List<OrderItemDO> orderItemDOList = orderItemMapper.selectByOrderIdAndDeleted(orderId, DeletedStatusEnum.DELETED_NO.getValue());
List<OrderItemDO> orderItemDOList = orderItemMapper.selectByDeletedAndOrderId(orderId, DeletedStatusEnum.DELETED_NO.getValue());
Integer orderPayAmount = orderCommon.calculatedAmount(orderItemDOList);
orderMapper.updateById(new OrderDO().setId(orderId).setPayAmount(orderPayAmount));
return CommonResult.success(null);
@ -341,9 +341,8 @@ public class OrderServiceImpl implements OrderService {
// 关闭订单修改状态 item
orderItemMapper.updateByOrderId(
new OrderItemDO()
.setOrderId(orderId)
.setStatus(OrderStatusEnum.CLOSED.getValue())
orderId,
new OrderItemDO().setStatus(OrderStatusEnum.CLOSED.getValue())
);
// 关闭订单修改状态 order
@ -360,7 +359,7 @@ public class OrderServiceImpl implements OrderService {
// 获取所有订单 items
List<OrderItemDO> allOrderItems = orderItemMapper
.selectByOrderIdAndDeleted(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
.selectByDeletedAndOrderId(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
// 当前需要发货订单检查 id status
List<OrderItemDO> needDeliveryOrderItems = allOrderItems.stream()
@ -425,7 +424,7 @@ public class OrderServiceImpl implements OrderService {
// 获取当前有效的订单 item
List<OrderItemDO> orderItemDOList = orderItemMapper
.selectByOrderIdAndDeleted(orderId, DeletedStatusEnum.DELETED_NO.getValue());
.selectByDeletedAndOrderId(orderId, DeletedStatusEnum.DELETED_NO.getValue());
List<OrderItemDO> effectiveOrderItems = orderItemDOList.stream()
.filter(orderItemDO -> !orderItemIds.contains(orderItemDO.getId()))
@ -453,6 +452,36 @@ public class OrderServiceImpl implements OrderService {
return CommonResult.success(null);
}
@Override
public CommonResult confirmReceiving(Integer userId, Integer orderId) {
OrderDO orderDO = orderMapper.selectById(orderId);
// 是否该用户的订单
if (!userId.equals(orderDO.getUserId())) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_USER_ORDER.getCode());
}
if (OrderStatusEnum.ALREADY_SHIPMENT.getValue() != orderDO.getStatus()) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_UNABLE_CONFIRM_ORDER.getCode());
}
orderMapper.updateById(
new OrderDO()
.setId(orderId)
.setReceiverTime(new Date())
.setStatus(OrderStatusEnum.COMPLETED.getValue())
);
orderItemMapper.updateByOrderId(
orderId,
new OrderItemDO()
.setStatus(OrderStatusEnum.COMPLETED.getValue())
.setReceiverTime(new Date())
);
return CommonResult.success(null);
}
@Override
public CommonResult updateLogistics(OrderLogisticsUpdateDTO orderLogisticsDTO) {
OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderLogisticsDTO);

View File

@ -34,12 +34,12 @@
-->
<sql id="updateFieldSql" >
<set>
<!--<if test="orderItemDO.orderId != null">-->
<!--, order_id = #{orderItemDO.orderId}-->
<!--</if>-->
<!--<if test="orderItemDO.orderNo != null">-->
<!--, order_no = #{orderItemDO.orderNo}-->
<!--</if>-->
<if test="orderItemDO.orderId != null">
, order_id = #{orderItemDO.orderId}
</if>
<if test="orderItemDO.orderNo != null">
, order_no = #{orderItemDO.orderNo}
</if>
<if test="orderItemDO.orderLogisticsId != null">
, order_logistics_id = #{orderItemDO.orderLogisticsId}
</if>
@ -123,7 +123,7 @@
<update id="updateByOrderId">
UPDATE `order_item`
<include refid="updateFieldSql" />
WHERE order_id = #{orderItemDO.orderId}
WHERE order_id = #{orderId}
</update>
<!--
@ -142,7 +142,7 @@
<!--
查询 - 根据 orderId 下的 item
-->
<select id="selectByOrderIdAndDeleted" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
<select id="selectByDeletedAndOrderId" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
SELECT * FROM `order_item`
WHERE 1=1
<if test="deleted">
@ -156,7 +156,7 @@
<!--
查询 - 根据 orderIds 和 status
-->
<select id="selectByOrderIdsAndDeleted" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
<select id="selectByDeletedAndOrderIds" resultType="cn.iocoder.mall.order.biz.dataobject.OrderItemDO">
SELECT
<include refid="FIELDS" />
FROM `order_item`

View File

@ -0,0 +1,49 @@
<?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.OrderLogisticsDetailMapper">
<sql id="FIELDS">
id
,
order_logistics_id,
logistics_time,
logistics_information,
create_time,
update_time
</sql>
<!--
插入
-->
<insert id="insert" parameterType="CartItemDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO cart_item (order_logistics_id, logistics_time, logistics_information,
create_time, update_time)
VALUES (#{orderLogisticsId}, #{logisticsTime}, #{logisticsInformation},
#{createTime}, #{updateTime})
</insert>
<!--
查询 - 根据 物流id
-->
<select id="selectByOrderLogisticsId"
resultType="cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDetailDO">
SELECT
<include refid="FIELDS"/>
FROM order_logistics_detail
WHERE order_logistics_id = #{orderLogisticsId}
</select>
<!--
查询 - 根据 物流ids
-->
<select id="selectByOrderLogisticsIds"
resultType="cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDetailDO">
SELECT
<include refid="FIELDS"/>
FROM order_logistics_detail
WHERE order_logistics_id IN
<foreach collection="orderLogisticsIds" item="orderLogisticsId" separator="," open="(" close=")">
#{orderLogisticsId}
</foreach>
</select>
</mapper>

View File

@ -54,7 +54,7 @@
</update>
<!--
查询 - 根据 orderId
查询 - 根据 ids
-->
<select id="selectByIds" resultType="cn.iocoder.mall.order.biz.dataobject.OrderLogisticsDO">
SELECT