From 6d2289d5278d5a0a46c737e6709d013490feaa6a Mon Sep 17 00:00:00 2001 From: Stormeye Wu Date: Thu, 8 Aug 2019 19:50:24 +0800 Subject: [PATCH] =?UTF-8?q?[POS][=E4=BF=AE=E6=94=B9]:=E9=A2=84=E6=A0=B8?= =?UTF-8?q?=E9=94=80/=E6=A0=B8=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iformall/controller/PosController.java | 69 ++++- .../java/com/iformall/service/PosService.java | 4 +- .../iformall/service/impl/PosServiceImpl.java | 290 ++++++++++++++++-- .../com/iformall/pos/test/PosAppTest.java | 6 +- .../java/com/iformall/common/ErrorCode.java | 6 +- .../java/com/iformall/pay/WxPayConstant.java | 16 + .../resources/mapper/WxCouponOrderMapper.xml | 4 +- 7 files changed, 352 insertions(+), 43 deletions(-) diff --git a/mallinkPosApi/src/main/java/com/iformall/controller/PosController.java b/mallinkPosApi/src/main/java/com/iformall/controller/PosController.java index bf3159b42..3aac166a2 100644 --- a/mallinkPosApi/src/main/java/com/iformall/controller/PosController.java +++ b/mallinkPosApi/src/main/java/com/iformall/controller/PosController.java @@ -69,7 +69,8 @@ public class PosController extends BaseController { "\"merchant_id\":\"string(必填)\"," + "\"mem_id\":\"string(选填)\"," + "\"mem_phone\":\"string(选填)\"," + - "\"pos_order_id\":\"string(必填)\"" + + "\"pos_order_id\":\"string(必填)\"," + + "\"pos_amount\":\"string(单位:分)(必填)\"," + "\"nonce_str\":\"string(必填)\"}") @PostMapping("/checkMem") public Map checkMem(@RequestBody Map params) { @@ -99,14 +100,16 @@ public class PosController extends BaseController { } } - @ApiOperation(value = "券是否可以核销", notes = "{" + + @ApiOperation(value = "券核销检查", notes = "{" + "\"dev_id\":\"string(必填)\"," + "\"tenant_id\":\"string(必填)\"," + "\"merchant_id\":\"string(必填)\"," + "\"bu_user_id\":\"string(必填)\"," + - "\"coupon_order_id\":\"string(必填)\" +" + - "\"nonce_str\":\"string(必填)\" +" + - "\"pos_order_id\":\"string(选填)\" }") + "\"coupon_order_id\":\"string(必填)\"," + + "\"nonce_str\":\"string(必填)\"," + + "\"verify\":\"independent, pay(必填)\"," + + "\"pos_order_id\":\"string(选填)\"," + + "\"pos_amount\":\"单位(分)(选填)\"}") @PostMapping("/checkCouponOrderForVerify") public Map checkCouponOrderVerify(@RequestBody Map params) { JSONObject payContent = new JSONObject(); @@ -121,7 +124,7 @@ public class PosController extends BaseController { logger.info("resKey: " + resKey); try { - retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.CHECK); + retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.CHECK); return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", WxPayConstant.RET_SUCCESS, null); } catch (MallinkException e) { @@ -140,9 +143,10 @@ public class PosController extends BaseController { "\"tenant_id\":\"string(必填)\"," + "\"merchant_id\":\"string(必填)\"," + "\"bu_user_id\":\"string(必填)\"," + - "\"coupon_order_id\":\"string(必填)\" +" + - "\"nonce_str\":\"string(必填)\" +" + - "\"pos_order_id\":\"string(必填)\" }") + "\"coupon_order_id\":\"string(必填)\"," + + "\"nonce_str\":\"string(必填)\"," + + "\"pos_order_id\":\"string(必填)\"," + + "\"pos_amount\":\"string(必填)\"}") @PostMapping("/couponOrderPreVerify") public Map couponOrderPreVerify(@RequestBody Map params) { JSONObject payContent = new JSONObject(); @@ -157,7 +161,7 @@ public class PosController extends BaseController { logger.info("resKey: " + resKey); try { - retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.PRE_VERIFY); + retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.PRE_VERIFY); return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", WxPayConstant.RET_SUCCESS, null); } catch (MallinkException e) { @@ -229,7 +233,7 @@ public class PosController extends BaseController { logger.info("resKey: " + resKey); try { - retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.VERIFY_INDEPENT); + retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.VERIFY_INDEPENT); return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", WxPayConstant.RET_SUCCESS, null); } catch (MallinkException e) { @@ -243,7 +247,7 @@ public class PosController extends BaseController { } } - @ApiOperation(value = "券交易核销", notes = "{" + + @ApiOperation(value = "券交易核销-单个优惠券接口", notes = "{" + "\"dev_id\":\"string(必填)\"," + "\"tenant_id\":\"string(必填)\"," + "\"merchant_id\":\"string(必填)\"," + @@ -251,7 +255,7 @@ public class PosController extends BaseController { "\"coupon_order_id\":\"string(必填)\" +" + "\"nonce_str\":\"string(必填)\" +" + "\"pos_order_id\":\"string(必填)\" }") - @PostMapping("/couponOrderPayVerify") + @PostMapping("/couponOrderPayVerifyOne") public Map couponOrderPayVerify(@RequestBody Map params) { JSONObject payContent = new JSONObject(); @@ -265,7 +269,44 @@ public class PosController extends BaseController { logger.info("resKey: " + resKey); try { - retMap = posService.couponOrderVerifyDoSomething(params, EnumVerifyActionType.VERIFY_PAY); + retMap = posService.couponOrderVerifyDo(params, EnumVerifyActionType.VERIFY_PAY); + return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", + WxPayConstant.RET_SUCCESS, null); + } catch (MallinkException e) { + return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", + WxPayConstant.RET_FAIL, + e.getErrorCode(), e.getMessage()); + } catch (Exception e) { + return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", + WxPayConstant.RET_FAIL, + 500, e.getMessage()); + } + } + + @ApiOperation(value = "券交易核销-优惠券列表接口", notes = "{" + + "\"dev_id\":\"string(必填)\"," + + "\"nonce_str\":\"string(必填)\"" + + "\"tenant_id\":\"string(必填)\"," + + "\"merchant_id\":\"string(必填)\"," + + "\"bu_user_id\":\"string(必填)\"," + + "\"sel_co_list\":\"json array(必填),例[\"1\",\"2\",\"3\"]\"" + + "\"pos_order_id\":\"string(必填)\"" + + "\"pay_amount\":\"单位(分)(必填)\" }") + @PostMapping("/couponOrderPayVerifyList") + public Map couponOrderPayVerifyList(@RequestBody Map params) { + JSONObject payContent = new JSONObject(); + + // 1. check sign + Map retMap = checkSign(params, payContent); + if (retMap != null) { + // 签名相关异常返回 + return retMap; + } + String resKey = payContent.getString("resKey"); + logger.info("resKey: " + resKey); + + try { + retMap = posService.couponOrderVerifyListDo(params, EnumVerifyActionType.VERIFY_PAY); return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "", WxPayConstant.RET_SUCCESS, null); } catch (MallinkException e) { diff --git a/mallinkPosApi/src/main/java/com/iformall/service/PosService.java b/mallinkPosApi/src/main/java/com/iformall/service/PosService.java index 0697b2fa2..5be2884a9 100644 --- a/mallinkPosApi/src/main/java/com/iformall/service/PosService.java +++ b/mallinkPosApi/src/main/java/com/iformall/service/PosService.java @@ -22,7 +22,9 @@ public interface PosService { */ Map checkMember(Map params) throws MallinkException; - Map couponOrderVerifyDoSomething(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException; + Map couponOrderVerifyDo(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException; + + Map couponOrderVerifyListDo(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException; Map couponOrderVerifyCancel(Map params, EnumVerifyActionType actionType) throws MallinkException; } diff --git a/mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java b/mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java index 0d4b097c4..f6010bf07 100644 --- a/mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java +++ b/mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java @@ -1,5 +1,6 @@ package com.iformall.service.impl; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.iformall.common.ErrorCode; import com.iformall.domain.po.*; @@ -14,10 +15,12 @@ import com.iformall.mapper.WxOrderMapper; import com.iformall.pay.WxPayConstant; import com.iformall.service.*; import lombok.AllArgsConstructor; +import net.sf.saxon.expr.Component; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestBody; @@ -25,6 +28,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Service @AllArgsConstructor @@ -83,11 +87,12 @@ public class PosServiceImpl implements PosService { Map retMap = new HashMap<>(); String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数 - String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID - String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID - String memIdStr = params.get(WxPayConstant.MEM_ID); // 会员ID - String memPhoneStr = params.get(WxPayConstant.MEM_PHONE); // 会员手机 - String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID + String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID + String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID + String memIdStr = params.get(WxPayConstant.MEM_ID); // 会员ID + String memPhoneStr = params.get(WxPayConstant.MEM_PHONE); // 会员手机 + String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID + String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单金额(单位:分) if (StringUtils.isBlank(tenantId)) { String errMessage = "request params[tenant_id] error."; @@ -104,6 +109,11 @@ public class PosServiceImpl implements PosService { logger.error(errMessage); throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); } + if (StringUtils.isBlank(posAmountStr)) { + String errMessage = "request params[pos_amount] error."; + logger.error(errMessage); + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } if (StringUtils.isBlank(memIdStr) && StringUtils.isBlank(memPhoneStr)) { String errMessage = "please give one value for mem_id or mem_phone"; @@ -135,9 +145,11 @@ public class PosServiceImpl implements PosService { } Long merchantId, posOrderId; + Integer posAmount = 0; try { merchantId = Long.valueOf(merchantIdStr); posOrderId = Long.valueOf(posOrderIdStr); + posAmount = Integer.valueOf(posAmountStr); } catch (NumberFormatException e) { logger.error(e.getMessage()); throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR); @@ -155,24 +167,32 @@ public class PosServiceImpl implements PosService { level = levelConfig.getLevel(); } } + Integer discount = 100; WxLevelMerchant levelMerchant = new WxLevelMerchant(); levelMerchant.setTenantId(tenantId); levelMerchant.setLevelId(levelId); levelMerchant.setMerchantId(merchantId); List levelMerchantList = levelConfigService.findListCVo(levelMerchant); - if(levelMerchantList.size() >= 1) { + if (levelMerchantList.size() >= 1) { WxLevelMerchantCVo levelMerchantCVo = levelMerchantList.get(0); - if(levelMerchantCVo != null) { - retMap.put("discount", levelMerchantCVo.getDiscount().toString()); - retMap.put("levelMerchant", levelMerchantCVo.toString()); + if (levelMerchantCVo != null) { + discount = levelMerchantCVo.getDiscount(); + retMap.put(WxPayConstant.MEM_DISCOUNT, discount.toString()); + // retMap.put("levelMerchant", levelMerchantCVo.toString()); } } else { - retMap.put("discount", "100"); + retMap.put(WxPayConstant.MEM_DISCOUNT, "100"); } - retMap.put("id", user.getId().toString()); - retMap.put("phone", user.getPhone()); - retMap.put("level", level); + Double remainAmountD = posAmount * 1.0D * discount / 100; + long remainAmount = Math.round(remainAmountD); + + + retMap.put(WxPayConstant.MEM_ID, user.getId().toString()); + retMap.put(WxPayConstant.MEM_PHONE, user.getPhone()); + retMap.put(WxPayConstant.MEM_LEVEL, level); + retMap.put(WxPayConstant.ORG_AMOUNT, posAmountStr); + retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(remainAmount)); // 优惠券列表 Map coQ = new HashMap<>(); @@ -181,12 +201,26 @@ public class PosServiceImpl implements PosService { coQ.put("merchantId", merchantId); coQ.put("posOrderId", posOrderId); List couponOrderList = couponOrderService.findAvailCouponOrder(coQ); - retMap.put("avail_co_list", couponOrderList.toString()); + if (couponOrderList.size() > 0) { + retMap.put(WxPayConstant.AVAIL_CO_LIST, + JSONArray.toJSONString( + couponOrderList + .stream() + .filter(co -> + (co.get("type") == EnumCouponType.COUPON_MULTIMCH.getCode() || + co.get("type") == EnumCouponType.COUPON_MANJIAN.getCode() || + co.get("type") == EnumCouponType.COUPON_DAIJIN.getCode() + )) + .collect(Collectors.toList()) + )); + } else { + retMap.put(WxPayConstant.AVAIL_CO_LIST, "[]"); + } return retMap; } @Override - public Map couponOrderVerifyDoSomething(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException { + public Map couponOrderVerifyDo(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException { Map retMap = new HashMap<>(); String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数 @@ -194,7 +228,8 @@ public class PosServiceImpl implements PosService { String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID String couponOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // 券ID - String posOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // POS订单ID + String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID + String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单总额(单位:分) if (StringUtils.isBlank(tenantId)) { String errMessage = "request params[tenant_id] error."; @@ -214,22 +249,129 @@ public class PosServiceImpl implements PosService { String errMessage = "request params[coupon_order_id] error."; throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); } + if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || + actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) || + actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + if (StringUtils.isBlank(posOrderIdStr)) { + String errMessage = "request params[pos_order_id] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + } + if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || + actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + if (StringUtils.isBlank(posAmountStr)) { + String errMessage = "request params[pos_amount] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + } + + Long merchantId, buUserId, posOrderId = 0L; + Integer posAmount = 0; + try { + merchantId = Long.valueOf(merchantIdStr); + buUserId = Long.valueOf(buUserIdStr); + if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || + actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) || + actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + posOrderId = Long.valueOf(posOrderIdStr); + } + if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || + actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + posAmount = Integer.valueOf(posAmount); + } + } catch (NumberFormatException e) { + logger.error(e.getMessage()); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), e.getMessage()); + } + // 2. check merchant + WxMerchant merchant = merchantService.getById(merchantId); + if (merchant == null) { + logger.error(ErrorCode.MERCHANT_INFO_NOT_FOUND.getMessage() + ": " + merchantIdStr); + throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND); + } + if (merchant.getIsDel().equals(EnumDelStatus.DEL.getCode()) || merchant.getStatus().equals(EnumMerchantStatus.NOT_VALID.getCode())) { + logger.error(ErrorCode.MERCHANT_INFO_NOT_VALID.getMessage() + ": " + merchantIdStr); + throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_VALID); + } + // 3. check buUser + WxMerchantBUser buUser = merchantBUserService.getById(buUserId); + if (buUser == null) { + logger.error(ErrorCode.USER_IS_EMPTY.getMessage() + ": " + buUserIdStr); + throw new MallinkException(ErrorCode.USER_IS_EMPTY); + } + if (!buUser.getMerchantId().equals(merchantId)) { + logger.error(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG.getMessage() + ": " + buUserIdStr); + throw new MallinkException(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG); + } + + JSONArray coRetArr = new JSONArray(); + if (couponOrderIdStr != null) { + try { + Map oneRetMap = doVerifyActionForOneCouponOrder(actionType, + tenantId, merchantIdStr, merchantId, + buUserIdStr, buUserId, + posOrderIdStr, posOrderId, posAmount, + couponOrderIdStr); + coRetArr.add(oneRetMap); + } catch (MallinkException e) { + throw new MallinkException(e.getErrorCode(), e.getMessage()); + } + } + retMap.put("ret", coRetArr.toJSONString()); + return retMap; + } + + @Override + public Map couponOrderVerifyListDo(@RequestBody Map params, EnumVerifyActionType actionType) throws MallinkException { + Map retMap = new HashMap<>(); + + String nonceStr = params.get(WxPayConstant.NONCE_STR); // 随机数 + String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID + String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID + String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID + String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID + String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单总额(单位:分) + String selCoListStr = params.get(WxPayConstant.SELECTED_COUPON_ORDER_LIST); // 选中的优惠券列表 + + if (StringUtils.isBlank(tenantId)) { + String errMessage = "request params[tenant_id] error."; + logger.error(errMessage); + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + if (StringUtils.isBlank(merchantIdStr)) { + String errMessage = "request params[merchant_id] error."; + logger.error(errMessage); + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + if (StringUtils.isBlank(buUserIdStr)) { + String errMessage = "request params[bu_user_id] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + if (StringUtils.isBlank(selCoListStr)) { + String errMessage = "request params[sel_co_list] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT)) { if (StringUtils.isBlank(posOrderIdStr)) { String errMessage = "request params[pos_order_id] error."; throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); } + if (StringUtils.isBlank(posAmountStr)) { + String errMessage = "request params[pos_amount] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } } - Long merchantId, buUserId, couponOrderId, posOrderId = 0L; + Long merchantId, buUserId, posOrderId = 0L; + Integer posAmount = 0; try { merchantId = Long.valueOf(merchantIdStr); buUserId = Long.valueOf(buUserIdStr); - couponOrderId = Long.valueOf(couponOrderIdStr); if (actionType.equals(EnumVerifyActionType.PRE_VERIFY) || actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT) || actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { posOrderId = Long.valueOf(posOrderIdStr); + posAmount = Integer.valueOf(posAmountStr); } } catch (NumberFormatException e) { logger.error(e.getMessage()); @@ -255,6 +397,40 @@ public class PosServiceImpl implements PosService { logger.error(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG.getMessage() + ": " + buUserIdStr); throw new MallinkException(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG); } + + JSONArray selCoArr = JSONObject.parseArray(selCoListStr); + if (selCoArr.size() <= 0) { + String errMessage = "request params[sel_co_list] error."; + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage); + } + + JSONArray coRetArr = new JSONArray(); + for(int i=0;i oneRetMap = doVerifyActionForOneCouponOrder(actionType, + tenantId, merchantIdStr, merchantId, + buUserIdStr, buUserId, + posOrderIdStr, posOrderId, posAmount, + couponOrderIdStr); + coRetArr.add(oneRetMap); + } catch (MallinkException e) { + throw new MallinkException(e.getErrorCode(), e.getMessage()); + } + } + } + retMap.put("ret", coRetArr.toJSONString()); + return retMap; + } + + private Map doVerifyActionForOneCouponOrder( + EnumVerifyActionType actionType, + String tenantId, String merchantIdStr, Long merchantId, + String buUserIdStr, Long buUserId, + String posOrderIdStr, Long posOrderId, Integer posAmount, + String couponOrderIdStr) { + Map retMap = new HashMap<>(); // 4. check couponOrderId WxCouponOrderCVo couponOrderCVo = couponOrderService.detailCUserVo(couponOrderIdStr); if (couponOrderCVo == null) { @@ -262,6 +438,8 @@ public class PosServiceImpl implements PosService { throw new MallinkException(ErrorCode.COUPON_ORDER_IS_NULL); } + Long couponOrderId = couponOrderCVo.getId(); + // 5. get coupon WxCoupon wxCoupon = couponMapper.selectByPrimaryKey(couponOrderCVo.getCouponId()); if (wxCoupon == null) { @@ -281,6 +459,7 @@ public class PosServiceImpl implements PosService { throw new MallinkException(ErrorCode.COUPON_ORDER_IS_EARLIER_THAN_VALIDDATE); } } + // 6. 检查适用门店 WxCouponMerchant wxCouponMerchant = new WxCouponMerchant(); wxCouponMerchant.setProductId(couponOrderCVo.getCouponId()); @@ -334,12 +513,27 @@ public class PosServiceImpl implements PosService { throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL); } logger.info("券可以被核销: " + couponOrderIdStr); + retMap.put(WxPayConstant.ID, couponOrderIdStr); + retMap.put(WxPayConstant.CHECK, "true"); return retMap; } else if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) { logger.info("券可以被核销: " + couponOrderIdStr); + retMap.put(WxPayConstant.ID, couponOrderIdStr); + retMap.put(WxPayConstant.CHECK, "true"); return retMap; } } else if (actionType.equals(EnumVerifyActionType.PRE_VERIFY)) { + if (couponOrderCVo.getPrice() > posAmount) { + logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE); + } + if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MANJIAN) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_DAIJIN) + )) { + logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT); + } if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode())) { logger.info("券已被预核销: " + couponOrderIdStr); if (!couponOrderCVo.getBUserId().equals(buUserId)) { @@ -357,12 +551,22 @@ public class PosServiceImpl implements PosService { logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL.getMessage() + ": " + posOrderIdStr); throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_NOT_EQUAL); } + retMap.put(WxPayConstant.ID, couponOrderIdStr); + retMap.put(WxPayConstant.PRE_VERIFY, "true"); + retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice())); + retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice())); + posAmount = posAmount - couponOrderCVo.getPrice(); return retMap; } if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) { logger.info("券可以被预核销: " + couponOrderIdStr); try { doPreVerify(couponOrderCVo, buUserId, posOrderId); + retMap.put(WxPayConstant.ID, couponOrderIdStr); + retMap.put(WxPayConstant.PRE_VERIFY, "true"); + retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice())); + retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice())); + posAmount = posAmount - couponOrderCVo.getPrice(); return retMap; } catch (MallinkException e) { logger.error(e.getMessage()); @@ -374,6 +578,29 @@ public class PosServiceImpl implements PosService { } } else { // if (actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT ) ||actionType.equals(EnumVerifyActionType.VERIFY_PAY)) + if (actionType.equals(EnumVerifyActionType.VERIFY_INDEPENT)) { + if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH.getCode()) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_LIPIN.getCode()) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_PRESS.getCode()) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_GROUP.getCode()) + )) { + logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT); + } + } + if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + if (!(couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MULTIMCH.getCode()) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_MANJIAN.getCode()) || + couponOrderCVo.getCouponType().equals(EnumCouponType.COUPON_DAIJIN.getCode()) + )) { + logger.error(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_COUPON_TYPE_NOT_SUPPORT); + } + if (couponOrderCVo.getPrice() > posAmount) { + logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE); + } + } boolean blVerify = false; if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode())) { logger.info("券已被预核销: " + couponOrderIdStr); @@ -381,6 +608,12 @@ public class PosServiceImpl implements PosService { logger.error(ErrorCode.VERIFY_PRE_BUSER_NOT_EQUAL.getMessage() + ": " + buUserIdStr); throw new MallinkException(ErrorCode.VERIFY_PRE_BUSER_NOT_EQUAL); } + if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + if (couponOrderCVo.getPrice() > posAmount) { + logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE); + } + } // check pos order是否一致 PosCouponOrderVerify posCouponOrderVerifyQ = new PosCouponOrderVerify(); posCouponOrderVerifyQ.setTenantId(tenantId); @@ -394,12 +627,23 @@ public class PosServiceImpl implements PosService { } blVerify = true; } else if (couponOrderCVo.getCouponOrderStatus().equals(EnumCouponOrderStatus.COUPON_ORDER_USE_WAIT.getCode())) { - logger.info("券可以被预核销: " + couponOrderIdStr); + if (actionType.equals(EnumVerifyActionType.VERIFY_PAY)) { + if (couponOrderCVo.getPrice() > posAmount) { + logger.error(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE.getMessage()); + throw new MallinkException(ErrorCode.VERIFY_PRE_POS_ORDER_PRICE_ISSUE); + } + } + logger.info("券可以被核销: " + couponOrderIdStr); blVerify = true; } if (blVerify) { try { doVerify(couponOrderCVo, wxCoupon, merchantId, buUserId, posOrderId, retMap); + retMap.put(WxPayConstant.ID, couponOrderIdStr); + retMap.put(WxPayConstant.VERIFY, "true"); + retMap.put(WxPayConstant.DEDUCT_AMOUNT, String.valueOf(couponOrderCVo.getPrice())); + retMap.put(WxPayConstant.REMAIN_AMOUNT, String.valueOf(posAmount - couponOrderCVo.getPrice())); + posAmount = posAmount - couponOrderCVo.getPrice(); return retMap; } catch (MallinkException e) { logger.error(e.getMessage()); @@ -410,6 +654,7 @@ public class PosServiceImpl implements PosService { } } } + String errMessage = "核销异常:未知的核销状态-" + couponOrderCVo.getCouponOrderStatus() + ", 核销action-" + actionType.getCode(); logger.error(errMessage); throw new MallinkException(500, errMessage); @@ -424,7 +669,7 @@ public class PosServiceImpl implements PosService { String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID String couponOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // 券ID - String posOrderIdStr = params.get(WxPayConstant.COUPON_ORDER_ID); // POS订单ID + String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID String forceStr = params.get(WxPayConstant.FORCE); // 是否强制 if (StringUtils.isBlank(tenantId)) { @@ -455,11 +700,10 @@ public class PosServiceImpl implements PosService { } } - Long merchantId, buUserId, couponOrderId, posOrderId = 0L; + Long merchantId, buUserId, posOrderId = 0L; try { merchantId = Long.valueOf(merchantIdStr); buUserId = Long.valueOf(buUserIdStr); - couponOrderId = Long.valueOf(couponOrderIdStr); posOrderId = Long.valueOf(posOrderIdStr); } catch (NumberFormatException e) { logger.error(e.getMessage()); @@ -567,7 +811,7 @@ public class PosServiceImpl implements PosService { couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.POS_PRE_VERIFY.getCode()); couponOrder.setBUserId(buUserId); couponOrder.setUpdateDate(new Date()); - num = couponOrderMapper.updateVerifyCouponOrderStatus(couponOrder); + num = couponOrderMapper.updateVerifyCouponOrder(couponOrder); } catch (Exception e) { logger.error("db failed: couponOrder-" + couponOrderCVo.getId() + ", e:" + e.getMessage()); throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); diff --git a/mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java b/mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java index ca1819d8a..334afcdee 100644 --- a/mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java +++ b/mallinkPosApi/src/test/java/com/iformall/pos/test/PosAppTest.java @@ -109,6 +109,7 @@ public class PosAppTest { // reqObj.put(WxPayConstant.MEM_ID, "318314000718200832"); reqObj.put(WxPayConstant.MEM_PHONE, "13910154397"); reqObj.put(WxPayConstant.POS_ORDER_ID, "1"); + reqObj.put(WxPayConstant.POS_AMOUNT, "100"); reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey)); String reqJsonStr = JSONObject.toJSONString(reqObj); RequestBuilder request = MockMvcRequestBuilders.post("/checkMem") @@ -135,6 +136,7 @@ public class PosAppTest { reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744"); reqObj.put(WxPayConstant.NONCE_STR, "1"); reqObj.put(WxPayConstant.POS_ORDER_ID, "1"); + reqObj.put(WxPayConstant.POS_AMOUNT, "100"); reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey)); String reqJsonStr = JSONObject.toJSONString(reqObj); RequestBuilder request = MockMvcRequestBuilders.post("/checkCouponOrderForVerify") @@ -213,6 +215,7 @@ public class PosAppTest { reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744"); reqObj.put(WxPayConstant.NONCE_STR, "1"); reqObj.put(WxPayConstant.POS_ORDER_ID, "1"); + reqObj.put(WxPayConstant.POS_AMOUNT, "100"); reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey)); String reqJsonStr = JSONObject.toJSONString(reqObj); RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPreVerify") @@ -265,9 +268,10 @@ public class PosAppTest { reqObj.put(WxPayConstant.COUPON_ORDER_ID, "318978990426783744"); reqObj.put(WxPayConstant.NONCE_STR, "1"); reqObj.put(WxPayConstant.POS_ORDER_ID, "1"); + reqObj.put(WxPayConstant.POS_AMOUNT, "100"); reqObj.put(WxPayConstant.SIGN, WxPayment.createSignHMAC(reqObj, devReqKey)); String reqJsonStr = JSONObject.toJSONString(reqObj); - RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPayVerify") + RequestBuilder request = MockMvcRequestBuilders.post("/couponOrderPayVerifyOne") .contentType(MediaType.APPLICATION_JSON) .content(reqJsonStr); MvcResult result = mockMvc.perform(request).andReturn(); diff --git a/mallinkService/src/main/java/com/iformall/common/ErrorCode.java b/mallinkService/src/main/java/com/iformall/common/ErrorCode.java index 8573f2652..d68f50dc9 100644 --- a/mallinkService/src/main/java/com/iformall/common/ErrorCode.java +++ b/mallinkService/src/main/java/com/iformall/common/ErrorCode.java @@ -280,8 +280,10 @@ public enum ErrorCode{ VERIFY_PRE_BUSER_NOT_EQUAL(12051, "预核销操作员不一致,请先取消上次预核销"), VERIFY_PRE_POS_ORDER_IS_EMPTY(12052, "预核销POS订单ID为空"), VERIFY_PRE_POS_ORDER_NOT_EQUAL(12053, "预核销POS订单不一致,请先取消上次预核销"), - VERIFY_BUSER_MERCHANT_NOT_BELONG(12054, "核销员不属于此商户"), - VERIFY_POS_ORDER_NOT_EQUAL(12055, "核销POS订单不一致,请先取消上次预核销"), + VERIFY_PRE_POS_ORDER_PRICE_ISSUE(12054, "预核销券金额失败,请确定券金额是否合适"), + VERIFY_BUSER_MERCHANT_NOT_BELONG(12055, "核销员不属于此商户"), + VERIFY_POS_ORDER_NOT_EQUAL(12056, "核销POS订单不一致,请先取消上次预核销"), + VERIFY_COUPON_TYPE_NOT_SUPPORT(12057, "核销不支持此券类型"), MSG_REPEAT_SEND(12061, "短信重复发送"), VERIFY_COUPON_ORDER_MERCHANT_IS_NULL(12062, "卡券核销失败,请查看适用门店"), diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java b/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java index 756267714..56e61f0c3 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java @@ -22,8 +22,24 @@ public class WxPayConstant { public final static String MERCHANT_ID = "merchant_id"; public final static String BUSER_ID = "bu_user_id"; public final static String COUPON_ORDER_ID = "coupon_order_id"; + public final static String SELECTED_COUPON_ORDER_LIST = "sel_co_list"; public final static String POS_ORDER_ID = "pos_order_id"; + public final static String POS_AMOUNT = "pos_amount"; public final static String MEM_ID = "mem_id"; public final static String MEM_PHONE = "mem_phone"; + public final static String VERIFY_TYPE = "verify_type"; + + + public final static String MEM_DISCOUNT = "discount"; + public final static String MEM_LEVEL = "level"; + public final static String AVAIL_CO_LIST = "avail_co_list"; + public final static String ID = "id"; + public final static String CHECK = "check"; + public final static String PRE_VERIFY = "pre_verify"; + public final static String VERIFY = "verify"; + public final static String DEDUCT_AMOUNT = "deduct_amount"; + public final static String REMAIN_AMOUNT = "remain_amount"; + + public final static String ORG_AMOUNT = "org_amount"; } diff --git a/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml b/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml index b76e7fcbd..81b2efc72 100644 --- a/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml @@ -1044,7 +1044,7 @@