Authored by tanling

no message

Showing 24 changed files with 698 additions and 197 deletions
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.BuyerOrderGoods;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BuyerOrderGoodsMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -11,6 +14,8 @@ public interface BuyerOrderGoodsMapper {
BuyerOrderGoods selectByPrimaryKey(Integer id);
List<BuyerOrderGoods> selectByOrderCode(@Param("list") List<Long> orderCodeList);
int updateByPrimaryKeySelective(BuyerOrderGoods record);
int updateByPrimaryKey(BuyerOrderGoods record);
... ...
... ... @@ -3,6 +3,8 @@ package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.BuyerOrder;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BuyerOrderMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -17,5 +19,10 @@ public interface BuyerOrderMapper {
int updateByPrimaryKeySelective(BuyerOrder record);
int selectCntByUidStatus(@Param("uid") int uid, @Param("status") List<Integer> status);
List<BuyerOrder> selectListByUidStatus(@Param("uid") int uid, @Param("status") List<Integer> status,
@Param("offset")Integer offset, @Param("limit")Integer limit);
int updateByPrimaryKey(BuyerOrder record);
}
\ No newline at end of file
... ...
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import org.apache.ibatis.annotations.Param;
public interface BuyerOrderMetaMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -11,6 +12,8 @@ public interface BuyerOrderMetaMapper {
BuyerOrderMeta selectByPrimaryKey(Integer id);
BuyerOrderMeta selectByMetaKey(@Param("uid") int uid, @Param("orderCode") long orderCode, @Param("metaKey") String metaKey);
int updateByPrimaryKeySelective(BuyerOrderMeta record);
int updateByPrimaryKey(BuyerOrderMeta record);
... ...
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface SellerOrderGoodsMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -11,6 +14,9 @@ public interface SellerOrderGoodsMapper {
SellerOrderGoods selectByPrimaryKey(Integer id);
List<SellerOrderGoods> selectBySkups(@Param("list") List<Integer> skup);
int updateByPrimaryKeySelective(SellerOrderGoods record);
int updateByPrimaryKey(SellerOrderGoods record);
... ...
... ... @@ -11,12 +11,27 @@
<sql id="Base_Column_List">
id, order_code, skup, goods_price, goods_amount
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order_goods
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectByOrderCode" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order_goods
where 1=1
<if test="list != null">
and order_code in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from buyer_order_goods
where id = #{id,jdbcType=INTEGER}
... ...
... ... @@ -32,6 +32,42 @@
</select>
<select id="selectCntByUidStatus" resultType="java.lang.Integer">
select
count(1)
from buyer_order
where
uid = #{uid,jdbcType=INTEGER}
and order_status = 1
<if test="status != null">
and status in
<foreach item="item" index="index" collection="status" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</select>
<select id="selectListByUidStatus" resultMap="BaseResultMap">
select
count(1)
from buyer_order
where
uid = #{uid,jdbcType=INTEGER}
and order_status = 1
<if test="status != null">
and status in
<foreach item="item" index="index" collection="status" open="(" separator="," close=")">
#{item}
</foreach>
</if>
limit #{offset, jdbcType=INTEGER}, #{limit, jdbcType=INTEGER}
</select>
<select id="selectByOrderCode" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
... ...
... ... @@ -11,12 +11,25 @@
<sql id="Base_Column_List">
id, order_code, uid, meta_key, meta_value
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order_meta
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectByMetaKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order_meta
where uid = #{uid,jdbcType=INTEGER}
and order_code = #{orderCode,jdbcType=BIGINT}
and metaKey = #{metaKey,jdbcType=VARCHAR}
limit 1
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from buyer_order_meta
where id = #{id,jdbcType=INTEGER}
... ...
<?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="com.yohoufo.dal.order].SellerOrderGoodsMapper">
<mapper namespace="com.yohoufo.dal.order.SellerOrderGoodsMapper">
<resultMap id="BaseResultMap" type="com.yohoufo.dal.order.model.SellerOrderGoods">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="product_id" jdbcType="INTEGER" property="productId" />
... ... @@ -20,7 +20,7 @@
id, product_id, product_name, storage_id, depot_no, size_id, size_name, goods_id,
color_id, color_name, goods_price, status, image_url
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from seller_order_goods
... ... @@ -28,6 +28,19 @@
</select>
<select id="selectBySkups" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from seller_order_goods
where 1=1
<if test="list != null">
and id in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</select>
... ...
package com.yohoufo.order.common;
import java.util.Arrays;
import java.util.List;
public enum OrderListType {
WAITING_PAY(2, "待付款",
Arrays.asList(OrderStatus.WAITING_PAY.getCode())),
WAITING_SEND(3, "待发货",
Arrays.asList(OrderStatus.SELLER_SEND_OUT.getCode(),
OrderStatus.HAS_PAYED.getCode(),
OrderStatus.PLATFORM_CHECKING.getCode())),
WAITING_DELIVERY(4, "待收货",
Arrays.asList(OrderStatus.WAITING_RECEIVE.getCode())),
ORDER_SUCCESS(5, "交易成功",
Arrays.asList(OrderStatus.DONE.getCode())),
ORDER_FAILED(6, "交易失败", Arrays.asList(OrderStatus.SELLER_CANCEL_BEFORE_PAY.getCode(),
OrderStatus.SELLER_CANCEL_AFTER_PAY.getCode(),
OrderStatus.SEND_OUT_TIMEOUT.getCode(),
OrderStatus.CHECKING_FAKE.getCode(),
OrderStatus.BUYER_CANCEL_BEFORE_PAY.getCode(),
OrderStatus.BUYER_CANCEL_TIMEOUT.getCode(),
OrderStatus.CUSTOMER_SERVICE.getCode()));
int type;
String desc;
List<Integer> status;
OrderListType(int type, String desc, List<Integer> status) {
this.type = type;
this.desc = desc;
this.status = status;
}
/**
* 检查是否存在该中查询类型
* @param code
* @return
*/
public static OrderListType getOrderListType(int code){
for(OrderListType v : values()){
if(v.type == code){
return v;
}
}
return null;
}
public int getType() {
return type;
}
public String getDesc() {
return desc;
}
public List<Integer> getStatus() {
return status;
}
}
... ...
package com.yohoufo.order.common;
public enum OrderStatus {
public enum OrderStatus {
// 14:支付前取消,15:超时未支付取消,16:已支付,卖家发货前取消;17:客服取消
WAITING_PAY(0, "未付款"),
... ...
... ... @@ -15,4 +15,9 @@ public interface MetaKey {
String SELLER_FEE = "fee";
/**
* 预支付成功记录的appPayRequest
*/
String APP_PAY_REQUEST = "app_pay_request";
}
... ...
... ... @@ -41,5 +41,7 @@ public interface OrderConstant {
String EMPTY_ADDRESS_CODE = "000000";
String SPLIT_STR = "_";
}
... ...
package com.yohoufo.order.controller;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
import com.yohoufo.order.request.OrderListRequest;
import com.yohoufo.order.service.IBuyerOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/shopping")
@RequestMapping(value = "/buyerOrder")
public class BuyerOrderController {
... ... @@ -19,38 +19,26 @@ public class BuyerOrderController {
/**
* 结算
* @return
*/
@RequestMapping(params = "method=ufo.order.payment")
public ApiResponse payment(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup){
ShoppingPaymentResponse paymentResponse = buyerOrderService.payment(ShoppingRequest.builder().uid(uid).skup(skup).build());
return new ApiResponse.ApiResponseBuilder().code(200).data(paymentResponse).message("结算成功").build();
}
/**
* 提交订单成功
* @return
* [购买]订单列表
* 1:
* 2:待付款
* 3:待发货
* 4:待收货
* 5:交易成功
* 7:交易失败
*/
@RequestMapping(params = "method=ufo.order.submit")
public ApiResponse submit(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup,
@RequestParam(name = "channelNo") String channelNo,
@RequestParam(name = "addressId") String addressId,
@RequestParam(name = "clientType") String clientType){
ShoppingRequest request = ShoppingRequest.builder().uid(uid).skup(skup).channelNo(channelNo).clientType(clientType).addressId(addressId).build();
OrderSubmitResponse paymentResponse = buyerOrderService.submit(request);
return new ApiResponse.ApiResponseBuilder().code(200).data(paymentResponse).message("提交订单SUCCESS").build();
@RequestMapping(params = "method=app.buyer.list")
@ResponseBody
public ApiResponse getOrderList(@RequestParam("type") int type,
@RequestParam("uid") int uid,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "limit", required = false, defaultValue = "10") int limit) {
OrderListRequest orderListRequest = new OrderListRequest();
orderListRequest.setUid(uid);
orderListRequest.setType(type);
orderListRequest.setPage(page);
orderListRequest.setLimit(limit);
return null;
}
}
... ...
package com.yohoufo.order.controller;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
import com.yohoufo.order.service.IBuyerOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/shopping")
public class BuyerOrderController {
@Autowired
IBuyerOrderService buyerOrderService;
/**
* 结算
* @return
*/
@RequestMapping(params = "method=ufo.order.payment")
public ApiResponse payment(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup){
ShoppingPaymentResponse paymentResponse = buyerOrderService.payment(ShoppingRequest.builder().uid(uid).skup(skup).build());
return new ApiResponse.ApiResponseBuilder().code(200).data(paymentResponse).message("结算成功").build();
}
/**
* 提交订单成功
* @return
*/
@RequestMapping(params = "method=ufo.order.submit")
public ApiResponse submit(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup,
@RequestParam(name = "channelNo") String channelNo,
@RequestParam(name = "addressId") String addressId,
@RequestParam(name = "clientType") String clientType){
ShoppingRequest request = ShoppingRequest.builder().uid(uid).skup(skup).channelNo(channelNo).clientType(clientType).addressId(addressId).build();
OrderSubmitResponse paymentResponse = buyerOrderService.submit(request);
return new ApiResponse.ApiResponseBuilder().code(200).data(paymentResponse).message("提交订单SUCCESS").build();
}
/**
* [购买]订单列表
* 1:
* 2:待付款
* 3:待发货
* 4:待收货
* 5:交易成功
* 7:交易失败
*/
@RequestMapping(params = "method=app.buyer.list")
@ResponseBody
public ApiResponse getMyOrders(@RequestParam("type") int type,
@RequestParam("uid") Integer uid,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "limit", required = false, defaultValue = "10") int limit) {
return null;
}
}
... ...
package com.yohoufo.order.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Builder;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OrderListRequest {
int uid;
int type;
int page;
int limit;
}
... ...
package com.yohoufo.order.response;
import lombok.Data;
@Data
public class OrderInfo {
long orderCode;
int skup;
/**
* 实付价格
*/
String realPrice;
/**
* 商品题目
*/
String productName;
/**
* 商品图片
*/
String imageUrl;
String colorName;
String sizeName;
/**
*
*/
int leftTime;
}
... ...
package com.yohoufo.order.response;
import com.alibaba.fastjson.JSONObject;
import lombok.ToString;
@ToString
public class PrepayResponse {
public static final int SUCCESS = 200;
... ...
package com.yohoufo.order.service;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
public interface IBuyerOrderService {
/**
* 结算页数据
* @param request
* @return
*/
public ShoppingPaymentResponse payment(ShoppingRequest request);
/**
* 提交订单
* @param shoppingRequest
* @return
*/
public OrderSubmitResponse submit(ShoppingRequest shoppingRequest);
}
... ...
package com.yohoufo.order.service;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
public interface IBuyerOrderService {
/**
* 结算页数据
* @param request
* @return
*/
public ShoppingPaymentResponse payment(ShoppingRequest request);
/**
* 提交订单
* @param shoppingRequest
* @return
*/
public OrderSubmitResponse submit(ShoppingRequest shoppingRequest);
}
... ...
package com.yohoufo.order.service.impl;
import com.sun.xml.internal.ws.api.message.AddressingUtils;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yoho.service.model.request.UserAddressReqBO;
import com.yoho.service.model.response.UserAddressRspBO;
import com.yohoufo.common.utils.AddressUtil;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderGoods;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.SkupStatus;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.model.dto.OrderBuilder;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
import com.yohoufo.order.service.IOrdeCreationService;
import com.yohoufo.order.common.OrderListType;
import com.yohoufo.order.request.OrderListRequest;
import com.yohoufo.order.response.OrderInfo;
import com.yohoufo.order.service.IBuyerOrderService;
import com.yohoufo.order.service.support.ShoppingSupport;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class BuyerOrderServiceImpl implements IBuyerOrderService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
ShoppingSupport shoppingSupport;
BuyerOrderMapper buyerOrderMapper;
@Autowired
SellerOrderGoodsMapper sellerOrderGoodsMapper;
BuyerOrderGoodsMapper buyerOrderGoodsMapper;
@Autowired
OrderCodeGenerator orderCodeGenerator;
SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
IOrdeCreationService ordeCreationService;
@Autowired
ServiceCaller serviceCaller;
/**
* 结算页数据
* @param request
* @return
*/
public ShoppingPaymentResponse payment(ShoppingRequest request){
// 入口参数检查
if (request.getSkup() < 0 || request.getUid() <0){
logger.warn("payment uid or skup is null");
public void getOrderList(OrderListRequest request){
if (request.getUid() < 0){
logger.warn("getOrderList uid is {}", request.getUid());
throw new ServiceException(ServiceError.ORDER_UID_IS_EMPTY);
}
OrderListType orderListType = OrderListType.getOrderListType(request.getType());
if (orderListType == null){
logger.warn("getOrderList type invalidate, uid is {}, type is {}",request.getUid(), request.getType());
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// 检查 商品sku是否可售
SellerOrderGoods skupGood = checkSkupSellOrNot(request.getSkup());
request.setPage(request.getPage() > 0 ? request.getPage() : 1);
request.setLimit( request.getLimit() > 0 ? request.getLimit() : 10 );
ShoppingPaymentResponse response = new ShoppingPaymentResponse();
response.setPaymentWay(shoppingSupport.getPaymentWay());
response.setDeliveryWay(shoppingSupport.getDeliverWay());
response.setGoodsList(Arrays.asList(shoppingSupport.getGoodsInfo(skupGood)));
response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(skupGood));
// TODO 赔偿金计算
// response.setDamagesDesc(shoppingSupport.getDamagesDesc(null));
int total = buyerOrderMapper.selectCntByUidStatus(request.getUid(), orderListType.getStatus());
return response;
}
int limit = request.getLimit();
int offset = (request.getPage() - 1) * limit;
private SellerOrderGoods checkSkupSellOrNot(int skup) {
// skup是否是可售状态
SellerOrderGoods skupGood = sellerOrderGoodsMapper.selectByPrimaryKey(skup);
if (skupGood == null){
logger.warn("payment skup not exist, skup is {}", skup);
throw new ServiceException(ServiceError.ORDER_SKUP_CANNOT_SELL);
}
List<BuyerOrder> buyerOrderList = buyerOrderMapper.selectListByUidStatus(request.getUid(), orderListType.getStatus(),offset, limit);
// 不可售
if (skupGood.getStatus() == null
|| skupGood.getStatus().intValue() == SkupStatus.CAN_NOT_SELL.getCode()){
logger.warn("payment skup status, skup is {}", skup);
throw new ServiceException(ServiceError.ORDER_SKUP_CANNOT_SELL);
}
return skupGood;
}
List<Long> orderCodeList = buyerOrderList.stream().map(BuyerOrder::getOrderCode).collect(Collectors.toList());
// buyer_order_goods ===> skup+商品成交价
List<BuyerOrderGoods> buyerOrderGoodsList = buyerOrderGoodsMapper.selectByOrderCode(orderCodeList);
Map<Long, BuyerOrderGoods> buyerOrderGoodsMap = buyerOrderGoodsList.stream().collect(Collectors.toMap(BuyerOrderGoods::getOrderCode, Function.identity()));
/**
* 提交订单
* @param shoppingRequest
* @return
*/
public OrderSubmitResponse submit(ShoppingRequest shoppingRequest){
// 入口参数检查
if (shoppingRequest.getSkup() < 0
|| shoppingRequest.getUid() < 0
|| StringUtils.isEmpty(shoppingRequest.getAddressId())){
logger.warn("submit param is null");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
List<Integer> skups = buyerOrderGoodsList.stream().map(BuyerOrderGoods::getSkup).collect(Collectors.toList());
// seller_order_goods ===> 商品信息
List<SellerOrderGoods> sellerOrderGoodsList = sellerOrderGoodsMapper.selectBySkups(skups);
Map<Integer, SellerOrderGoods> sellerOrderGoodsMap = sellerOrderGoodsList.stream().collect(Collectors.toMap(SellerOrderGoods::getId, Function.identity()));
// 检查地址是否合法
int addressId = AddressUtil.getDecryptStr(shoppingRequest.getAddressId());
if (addressId < 0){
logger.warn("submit addressId invalidate, uid is {}, skup is {}, addressId is {}", shoppingRequest.getUid(),
shoppingRequest.getSkup(), shoppingRequest.getAddressId());
throw new ServiceException(ServiceError.ORDER_ADDRESSID_INVALIDATE);
}
// 检查skup是否可售
SellerOrderGoods skup = checkSkupSellOrNot(shoppingRequest.getSkup());
buyerOrderList.stream().forEach(buyerOrder -> {
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderCode(buyerOrder.getOrderCode());
orderInfo.setRealPrice(buyerOrder.getAmount() == null ? "" : buyerOrder.getAmount().toPlainString());
// 生成订单号
long orderCode = orderCodeGenerator.generate(OrderCodeType.BUYER_TYPE);
BuyerOrderGoods buyerOrderGoods = buyerOrderGoodsMap.get(buyerOrder.getOrderCode());
if (buyerOrderGoods == null){
return;
}
orderInfo.setSkup(buyerOrderGoods.getSkup());
UserAddressRspBO addressInfo = getAddressInfo(shoppingRequest, addressId);
SellerOrderGoods sellerOrderGoods = sellerOrderGoodsMap.get(buyerOrderGoods.getSkup());
orderInfo.setProductName(sellerOrderGoods.getProductName());
orderInfo.setImageUrl(sellerOrderGoods.getImageUrl());
orderInfo.setColorName(sellerOrderGoods.getColorName());
orderInfo.setSizeName(sellerOrderGoods.getSizeName());
// 减库存,skup更新成不可售,入库
BigDecimal shipFee = new BigDecimal(OrderConstant.DELIVERY_WAY_SF_COST);
OrderBuilder orderBuilder = OrderBuilder.builder()
.uid(shoppingRequest.getUid())
.skup(shoppingRequest.getSkup())
.orderCode(orderCode)
.productId(skup.getProductId())
.paymentType(OrderConstant.PAYMENT_ONLINE)
.deliverWay(OrderConstant.DELIVERY_WAY_SF)
.channelNo(shoppingRequest.getChannelNo())
.amount(skup.getGoodsPrice().add(shipFee))
.shipFee(shipFee)
.addressInfo(addressInfo)
.build();
// 订单状态显示
ordeCreationService.create(orderBuilder);
// 按钮显示
// 返回结果
return OrderSubmitResponse.builder().orderCode(orderCode).paymentStatus(OrderConstant.N_STR).build();
}
/**
* 获取用户信息
* @param shoppingRequest
* @param addressId
* @return
*/
private UserAddressRspBO getAddressInfo(ShoppingRequest shoppingRequest, int addressId) {
// 收货地址信息, 入口参数:uid, address_id
UserAddressReqBO userAddressReqBO = new UserAddressReqBO();
userAddressReqBO.setUid(shoppingRequest.getUid());
userAddressReqBO.setId(addressId);
//超时,使用默认地址,后续需要手动补充地址
UserAddressRspBO defaultResponse = new UserAddressRspBO();
defaultResponse.setAreaCode(OrderConstant.EMPTY_ADDRESS_CODE);
defaultResponse.setId(String.valueOf(addressId));
UserAddressRspBO userAddressBO = serviceCaller.asyncCall("users.getAddress", userAddressReqBO,
UserAddressRspBO.class, defaultResponse).get(500, TimeUnit.MILLISECONDS);
return userAddressBO;
}
});
}
}
... ...
... ... @@ -24,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class OrdeCreationServiceImpl implements IOrdeCreationService {
private final Logger logger = LoggerFactory.getLogger(ProductController.class);
private final Logger logger = LoggerFactory.getLogger(OrdeCreationServiceImpl.class);
@Autowired
SellerOrderGoodsMapper sellerOrderGoodsMapper;
... ...
... ... @@ -8,18 +8,22 @@ import com.yoho.error.exception.ServiceException;
import com.yohoufo.common.utils.HttpClient;
import com.yohoufo.common.utils.SignUtils;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.OrderStatus;
import com.yohoufo.order.common.Payment;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import com.yohoufo.order.service.IPaymentService;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -61,6 +65,9 @@ public class PaymentServiceImpl implements IPaymentService {
@Autowired
HttpClient httpClient;
@Autowired
BuyerOrderMetaMapper buyerOrderMetaMapper;
/**
* 机构商户号
*/
... ... @@ -94,8 +101,16 @@ public class PaymentServiceImpl implements IPaymentService {
// 卖家or买家订单,支付方式更新,返回实付金额
BigDecimal amount = checkUpdOrderCode(request);
// 向银联提下过单的,直接返回结果
PrepayResponse oldAppPayRequest = getAppPayRequest(request);
if (oldAppPayRequest != null){
logger.info("payment oldAppPayRequest orderCode is {}, uid is {}, oldAppPayRequest is {}",
request.getOrderCode(), request.getUid(), oldAppPayRequest);
return oldAppPayRequest;
}
// 生成预支付数据
JSONObject prepayData = buildPrepayData(request, payment.getValue(), amount);
JSONObject prepayData = buildPrepayData(request, payment, amount);
PrepayResponse response = new PrepayResponse();
... ... @@ -105,6 +120,10 @@ public class PaymentServiceImpl implements IPaymentService {
if (resultJSON.containsKey("errCode") && "SUCCESS".equals(resultJSON.getString("errCode"))){
response.setPrepayResult(PrepayResponse.SUCCESS);
response.setJsonObj(resultJSON.getJSONObject("appPayRequest"));
// 保存支付成功结果
saveAppPayRequest(request, response);
logger.info("payment success orderCode is {}", request.getOrderCode() );
return response;
}else {
... ... @@ -122,17 +141,52 @@ public class PaymentServiceImpl implements IPaymentService {
}
/**
* 获取前回的访问结果
* @param request
* @return
*/
private PrepayResponse getAppPayRequest(PaymentRequest request) {
BuyerOrderMeta buyerOrderMeta = buyerOrderMetaMapper.selectByMetaKey(request.getUid(), request.getOrderCode(), getMetaKey(request.getPayment()));
if (buyerOrderMeta == null || StringUtils.isEmpty(buyerOrderMeta.getMetaValue())){
return null;
}
try{
PrepayResponse response = JSON.parseObject(buyerOrderMeta.getMetaValue(), PrepayResponse.class);
return response;
}catch (Exception e){
}
return null;
}
private void saveAppPayRequest(PaymentRequest request, PrepayResponse response) {
BuyerOrderMeta buyerOrderMeta = new BuyerOrderMeta();
buyerOrderMeta.setUid(request.getUid());
buyerOrderMeta.setOrderCode(request.getOrderCode());
buyerOrderMeta.setMetaKey(getMetaKey(request.getPayment()));
buyerOrderMeta.setMetaValue(JSONObject.toJSONString(response));
// 记录appPayRequest
buyerOrderMetaMapper.insert(buyerOrderMeta);
}
public String getMetaKey(int payment){
return MetaKey.APP_PAY_REQUEST + OrderConstant.SPLIT_STR +payment;
}
/**
* 生成预支付数据
* @param request
* @param paymentVal
* @return
*/
private JSONObject buildPrepayData(PaymentRequest request, String paymentVal, BigDecimal amount) {
private JSONObject buildPrepayData(PaymentRequest request, Payment payment, BigDecimal amount) {
JSONObject prepayData = new JSONObject();
prepayData.put("msgSrc", msgSrc);
prepayData.put("msgType", paymentVal);
prepayData.put("msgType", payment.getValue());
prepayData.put("requestTimestamp", DateUtil.date2String(new Date(), OrderConstant.DATE_FORMAT));
prepayData.put("merOrderId", OrderConstant.ORDER_CODE_PRE + request.getOrderCode());
prepayData.put("merOrderId", getPayOrderCode(request.getOrderCode(), payment));
prepayData.put("mid", mid);
prepayData.put("tid", tid);
prepayData.put("instMid", INST_MID);
... ... @@ -144,6 +198,16 @@ public class PaymentServiceImpl implements IPaymentService {
return prepayData;
}
private String getPayOrderCode(long orderCode, Payment payment){
StringBuilder sb = new StringBuilder();
sb.append(OrderConstant.ORDER_CODE_PRE);
sb.append(orderCode);
sb.append(OrderConstant.SPLIT_STR);
sb.append(payment.getCode());
return sb.toString();
}
private BigDecimal checkUpdOrderCode(PaymentRequest request) {
// 根据订单号 反解:买家订单号 or 卖家订单号
CodeMeta codeMeta = orderCodeGenerator.expId(request.getOrderCode());
... ...
package com.yohoufo.order.service.impl;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yoho.service.model.request.UserAddressReqBO;
import com.yoho.service.model.response.UserAddressRspBO;
import com.yohoufo.common.utils.AddressUtil;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.SkupStatus;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.model.dto.OrderBuilder;
import com.yohoufo.order.request.ShoppingRequest;
import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
import com.yohoufo.order.service.IOrdeCreationService;
import com.yohoufo.order.service.IShoppingService;
import com.yohoufo.order.service.support.ShoppingSupport;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Service;
@Service
public class ShoppingServiceImpl implements IShoppingService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
ShoppingSupport shoppingSupport;
@Autowired
SellerOrderGoodsMapper sellerOrderGoodsMapper;
@Autowired
OrderCodeGenerator orderCodeGenerator;
@Autowired
IOrdeCreationService ordeCreationService;
@Autowired
ServiceCaller serviceCaller;
/**
* 结算页数据
* @param request
* @return
*/
public ShoppingPaymentResponse payment(ShoppingRequest request){
// 入口参数检查
if (request.getSkup() < 0 || request.getUid() <0){
logger.warn("payment uid or skup is null");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// 检查 商品sku是否可售
SellerOrderGoods skupGood = checkSkupSellOrNot(request.getSkup());
ShoppingPaymentResponse response = new ShoppingPaymentResponse();
response.setPaymentWay(shoppingSupport.getPaymentWay());
response.setDeliveryWay(shoppingSupport.getDeliverWay());
response.setGoodsList(Arrays.asList(shoppingSupport.getGoodsInfo(skupGood)));
response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(skupGood));
// TODO 赔偿金计算
// response.setDamagesDesc(shoppingSupport.getDamagesDesc(null));
return response;
}
private SellerOrderGoods checkSkupSellOrNot(int skup) {
// skup是否是可售状态
SellerOrderGoods skupGood = sellerOrderGoodsMapper.selectByPrimaryKey(skup);
if (skupGood == null){
logger.warn("payment skup not exist, skup is {}", skup);
throw new ServiceException(ServiceError.ORDER_SKUP_CANNOT_SELL);
}
// 不可售
if (skupGood.getStatus() == null
|| skupGood.getStatus().intValue() == SkupStatus.CAN_NOT_SELL.getCode()){
logger.warn("payment skup status, skup is {}", skup);
throw new ServiceException(ServiceError.ORDER_SKUP_CANNOT_SELL);
}
return skupGood;
}
/**
* 提交订单
* @param shoppingRequest
* @return
*/
public OrderSubmitResponse submit(ShoppingRequest shoppingRequest){
// 入口参数检查
if (shoppingRequest.getSkup() < 0
|| shoppingRequest.getUid() < 0
|| StringUtils.isEmpty(shoppingRequest.getAddressId())){
logger.warn("submit param is null");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// 检查地址是否合法
int addressId = AddressUtil.getDecryptStr(shoppingRequest.getAddressId());
if (addressId < 0){
logger.warn("submit addressId invalidate, uid is {}, skup is {}, addressId is {}", shoppingRequest.getUid(),
shoppingRequest.getSkup(), shoppingRequest.getAddressId());
throw new ServiceException(ServiceError.ORDER_ADDRESSID_INVALIDATE);
}
// 检查skup是否可售
SellerOrderGoods skup = checkSkupSellOrNot(shoppingRequest.getSkup());
// 生成订单号
long orderCode = orderCodeGenerator.generate(OrderCodeType.BUYER_TYPE);
UserAddressRspBO addressInfo = getAddressInfo(shoppingRequest, addressId);
// 减库存,skup更新成不可售,入库
BigDecimal shipFee = new BigDecimal(OrderConstant.DELIVERY_WAY_SF_COST);
OrderBuilder orderBuilder = OrderBuilder.builder()
.uid(shoppingRequest.getUid())
.skup(shoppingRequest.getSkup())
.orderCode(orderCode)
.productId(skup.getProductId())
.paymentType(OrderConstant.PAYMENT_ONLINE)
.deliverWay(OrderConstant.DELIVERY_WAY_SF)
.channelNo(shoppingRequest.getChannelNo())
.amount(skup.getGoodsPrice().add(shipFee))
.shipFee(shipFee)
.addressInfo(addressInfo)
.build();
ordeCreationService.create(orderBuilder);
// 返回结果
return OrderSubmitResponse.builder().orderCode(orderCode).paymentStatus(OrderConstant.N_STR).build();
}
/**
* 获取用户信息
* @param shoppingRequest
* @param addressId
* @return
*/
private UserAddressRspBO getAddressInfo(ShoppingRequest shoppingRequest, int addressId) {
// 收货地址信息, 入口参数:uid, address_id
UserAddressReqBO userAddressReqBO = new UserAddressReqBO();
userAddressReqBO.setUid(shoppingRequest.getUid());
userAddressReqBO.setId(addressId);
//超时,使用默认地址,后续需要手动补充地址
UserAddressRspBO defaultResponse = new UserAddressRspBO();
defaultResponse.setAreaCode(OrderConstant.EMPTY_ADDRESS_CODE);
defaultResponse.setId(String.valueOf(addressId));
UserAddressRspBO userAddressBO = serviceCaller.asyncCall("users.getAddress", userAddressReqBO,
UserAddressRspBO.class, defaultResponse).get(500, TimeUnit.MILLISECONDS);
return userAddressBO;
}
}
... ...
... ... @@ -36,17 +36,54 @@ public class PayTest {
@Test
public void testPrepay() throws Exception {
// TODO 30分钟之后,再跑一遍这个接口
JSONObject data = new JSONObject();
data.put("msgSrc","WWW.TEST.COM");
// 支付宝
data.put("msgType", "trade.precreate"); // 微信:wx.unifiedOrder, 支付宝:trade.precreate, 全民付:qmf.order, 银联云闪付:uac.appOrder
data.put("requestTimestamp", DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 支付宝- 31945075157
data.put("merOrderId", "319422222222224444");
data.put("merOrderId", "31949755697176593");
data.put("mid", "898310148160568"); //商户号 仅用于支付宝和云闪付
data.put("tid","00000001"); //终端号
data.put("instMid", "APPDEFAULT"); // 机构商户号
data.put("totalAmount", 1.0);
data.put("totalAmount", 1);
// 回调接口 http://api-test3.dev.yohocorp.com/payment/weixin_notify
data.put("notifyUrl", "http://testapi.yohops.com/payment/weixin_notify");
data.put("sign", getSign(data));
HttpClient httpClient = new HttpClient();
httpClient.init();
String result = httpClient.post(url, JSON.toJSONString(data));
System.out.println(result);
}
/**
* 预支付=下单接口 支付宝
*/
@Test
public void testPrepay3() throws Exception {
JSONObject data = new JSONObject();
data.put("msgSrc","WWW.TEST.COM");
// 支付宝
data.put("msgType", "trade.precreate"); // 微信:wx.unifiedOrder, 支付宝:trade.precreate, 全民付:qmf.order, 银联云闪付:uac.appOrder
data.put("requestTimestamp", DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 支付宝- 31945075157
data.put("merOrderId", "31949755697176593_a");
data.put("mid", "898310148160568"); //商户号 仅用于支付宝和云闪付
data.put("tid","00000001"); //终端号
data.put("instMid", "APPDEFAULT"); // 机构商户号
data.put("totalAmount", 1);
// 回调接口 http://api-test3.dev.yohocorp.com/payment/weixin_notify
data.put("notifyUrl", "http://testapi.yohops.com/payment/weixin_notify");
... ... @@ -54,7 +91,6 @@ public class PayTest {
data.put("sign", getSign(data));
String dataStr = "{\"totalAmount\":1.00,\"msgType\":\"trade.precreate\",\"requestTimestamp\":\"2018-09-17 17:02:33\",\"msgSrc\":\"WWW.TEST.COM\",\"sign\":\"e0ad8dd33deb6d93064b153e682232ce\",\"mid\":\"898310148160568\",\"notifyUrl\":\"http://testapi.yohops.com/payment/weixin_notify\",\"tid\":\"00000001\",\"merOrderId\":\"31949755628692241\",\"instMid\":\"APPDEFAULT\"}";
HttpClient httpClient = new HttpClient();
... ...