From c8b75b79486fa0dedeb996aefb961d8ec2ee1a8c Mon Sep 17 00:00:00 2001 From: hupeng Date: Mon, 24 Dec 2018 18:31:49 +0800 Subject: [PATCH] =?UTF-8?q?[=E7=B3=BB=E7=BB=9F][=E4=BF=AE=E5=A4=8D]:?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E8=B4=A6=E5=AE=9A=E6=97=B6=E9=87=8D?= =?UTF-8?q?=E8=AF=95,=E4=BF=AE=E5=A4=8D=E6=9F=A5=E8=AF=A2=E5=AE=8C?= =?UTF-8?q?=E7=BB=93=E5=88=86=E8=B4=A6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../schedule/SharingOrderRedoSchedule.java | 77 ++++++ .../service/WxProfitSharingOrderService.java | 6 + .../impl/WxProfitSharingOrderServiceImpl.java | 232 +++++++++++++----- 3 files changed, 259 insertions(+), 56 deletions(-) create mode 100644 mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java diff --git a/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java new file mode 100644 index 000000000..9b79bcb73 --- /dev/null +++ b/mallinkSchedule/src/main/java/com/iformall/schedule/SharingOrderRedoSchedule.java @@ -0,0 +1,77 @@ +package com.iformall.schedule; + +import com.iformall.common.ErrorCode; +import com.iformall.common.ResultData; +import com.iformall.domain.dto.WxSharingOrderDto; +import com.iformall.domain.po.WxProfitSharingOrder; +import com.iformall.enums.EnumProfitSharingOrderStatus; +import com.iformall.enums.EnumProfitSharingOrderType; +import com.iformall.mapper.WxPayOrderMapper; +import com.iformall.mapper.WxProfitSharingOrderMapper; +import com.iformall.service.WxProfitSharingOrderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class SharingOrderRedoSchedule { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private WxProfitSharingOrderService wxProfitSharingOrderService; + + @Autowired + private WxProfitSharingOrderMapper wxProfitSharingOrderMapper; + + + @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨02:00分账重试 + //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 + public void sharingOrderResultSchedule() { + + WxProfitSharingOrder wxProfitSharingOrder = new WxProfitSharingOrder(); + + wxProfitSharingOrder.setType(EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getCode()); + wxProfitSharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode()); + List list = wxProfitSharingOrderMapper.findList(wxProfitSharingOrder); + list.stream().forEach(sharingOrder->{ + try { + ResultData result = wxProfitSharingOrderService.redoSharingOrder(sharingOrder); + if (result.code != ResultData.SUCCESS) { + logger.error("分账重试失败:" + EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getMessage() + + " ID:" +sharingOrder.getId() + + " RES:" + result.message); + } + + } catch (Exception e){ + logger.error("分账重试失败:" + EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getMessage() + + " ID:" +sharingOrder.getId() + + " MSG:" + e.getMessage()); + } + }); + + + wxProfitSharingOrder.setType(EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getCode()); + wxProfitSharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode()); + list = wxProfitSharingOrderMapper.findList(wxProfitSharingOrder); + list.stream().forEach(sharingOrder->{ + try { + ResultData result = wxProfitSharingOrderService.redoSharingOrder(sharingOrder); + if (result.code != ResultData.SUCCESS) { + logger.error("分账重试失败:" + EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getMessage() + + " ID:" +sharingOrder.getId() + + " RES:" + result.message); + } + } catch (Exception e){ + logger.error("分账重试失败:" + EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getMessage() + + " ID:" +sharingOrder.getId() + + " MSG:" + e.getMessage()); + } + }); + + } +} \ No newline at end of file diff --git a/mallinkService/src/main/java/com/iformall/service/WxProfitSharingOrderService.java b/mallinkService/src/main/java/com/iformall/service/WxProfitSharingOrderService.java index a9ce9ea40..d9336eb96 100644 --- a/mallinkService/src/main/java/com/iformall/service/WxProfitSharingOrderService.java +++ b/mallinkService/src/main/java/com/iformall/service/WxProfitSharingOrderService.java @@ -17,6 +17,11 @@ public interface WxProfitSharingOrderService { */ ResultData createSharingOrder(WxSharingOrderDto wxSharingOrderDto); + /** + * 分账重试 + */ + ResultData redoSharingOrder(WxProfitSharingOrder sharingOrder); + /** * 查询分账订单 */ @@ -27,6 +32,7 @@ public interface WxProfitSharingOrderService { */ ResultData finishSharingOrder(WxSharingOrderDto sharingOrderDto); + PageInfo listAsPage(WxProfitSharingOrderQueryVo order, Integer pageNum, Integer pageSize); Map queryOrderSummary(String tenantId); diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java index b01a988e3..e6724dee5 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java @@ -117,6 +117,123 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ } + @Override + @Transactional(isolation=Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + public ResultData redoSharingOrder(WxProfitSharingOrder sharingOrder) { + final IdWorker idworker = IdWorker.get(); + + if (!sharingOrder.getType().equals(EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getCode()) && + !sharingOrder.getType().equals(EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getCode())) { + return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); + } + + WxPayOrder payOrder = wxPayOrderMapper.selectByPrimaryKey(sharingOrder.getOrderId()); + WxAppinfo appInfo = getAppinfo(payOrder.getcUserId()); + WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); + + List receivers; + + try { + receivers = JSONArray.parseArray(sharingOrder.getReceivers(), JSONObject.class); + if (receivers.size() <= 0) + return new ResultData(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); + } catch (Exception e) { + return new ResultData(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); + } + + final WxProfitSharingOrder frecord = sharingOrder; + List resultList = new ArrayList(); + try { + receivers.stream().forEach(receiver -> { + Date currentDate = new Date(); + WxProfitSharingResult result = new WxProfitSharingResult(); + result.setId(idworker.nextId()); + result.setTenantId(frecord.getTenantId()); + result.setMerchantId(frecord.getMerchantId()); + result.setSharingOrderId(frecord.getId()); + result.setSharingReceiverId(Long.valueOf(receiver.getString("description"))); + result.setPayAmount(receiver.getInteger("amount")); + result.setCreateTime(currentDate); + result.setUpdateTime(currentDate); + result.setSharingStatus(EnumProfitSharingResultStatus.PROFIT_SHARING_RESULT_PENDING.getCode()); + resultList.add(result); + }); + }catch (Exception e) { + return new ResultData(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); + } + + //分账提交 + WxProfitSharingP psCmd = new WxProfitSharingP(); + psCmd.setMch_id(payAccount.getMchId()); + psCmd.setSub_mch_id(payAccount.getSubMchId()); + psCmd.setAppid(appInfo.getParentAppId()); + psCmd.setSub_appid(appInfo.getAppId()); + psCmd.setNonce_str(Utility.generate32UUID()); + psCmd.setTransaction_id(sharingOrder.getTransaction()); + psCmd.setOut_order_no(sharingOrder.getId().toString()); + psCmd.setSign_type("HMAC-SHA256"); + psCmd.setReceivers(sharingOrder.getReceivers()); + + String response; + try { + psCmd.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(psCmd), payAccount.getApiKey())); + logger.info("request:" + psCmd.toString()); + if(sharingOrder.getType().equals(EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getCode())) { + response = WxProfitSharing.pushOrder(BeanUtils.toStringMap(psCmd), payAccount.getCertPath(), payAccount.getMchId()); + } else if(sharingOrder.getType().equals(EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getCode())) { + response = WxProfitSharing.pushMultiOrder(BeanUtils.toStringMap(psCmd), payAccount.getCertPath(), payAccount.getMchId()); + } else { + throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); + } + } catch (Exception e) { + sharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode()); + sharingOrder.setErrorMsg("REDO:"+ErrorCode.PROFIT_SHARING_REQUEST_FAILED.getMessage()); + sharingOrder.setUpdateTime(new Date()); + wxProfitSharingOrderMapper.updateByPrimaryKey(sharingOrder); + return new ResultData(ErrorCode.PROFIT_SHARING_REQUEST_FAILED); + } + + logger.info("response: " + response); + Map returnMap = WxPayment.xmlToMap(response); + String return_code = returnMap.get("return_code"); + + if (!"SUCCESS".equals(return_code)) { + sharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode()); + sharingOrder.setErrorMsg("REDO:"+returnMap.get("return_msg")); + sharingOrder.setUpdateTime(new Date()); + wxProfitSharingOrderMapper.updateByPrimaryKey(sharingOrder); + return new ResultData(ErrorCode.PROFIT_SHARING_REQUEST_FAILED.getCode(), returnMap.get("return_msg")); + } + + if (!WxPayment.verifyNotifyHMAC(returnMap,payAccount.getApiKey())){ + sharingOrder.setErrorMsg("REDO:"+ErrorCode.PROFIT_SHARING_RETURN_INVALID.getMessage()); + sharingOrder.setUpdateTime(new Date()); + wxProfitSharingOrderMapper.updateByPrimaryKey(sharingOrder); + return new ResultData(ErrorCode.PROFIT_SHARING_RETURN_INVALID.getCode()); + } + + String result_code = returnMap.get("result_code"); + if (!"SUCCESS".equals(result_code)) { + sharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode()); + sharingOrder.setUpdateTime(new Date()); + sharingOrder.setErrorMsg("REDO:"+returnMap.get("err_code_des")); + wxProfitSharingOrderMapper.updateByPrimaryKey(sharingOrder); + return new ResultData(ErrorCode.PROFIT_SHARING_APPLY_FAILED.getCode(), returnMap.get("err_code_des")); + } + + sharingOrder.setSharingOrderNo(returnMap.get("order_id")); + sharingOrder.setSharingStatus(EnumProfitSharingOrderStatus.PROFIT_SHARING_ACCEPTED.getCode()); + sharingOrder.setErrorMsg("REDO:重试分账成功"); + sharingOrder.setUpdateTime(new Date()); + wxProfitSharingOrderMapper.updateByPrimaryKey(sharingOrder); + for (WxProfitSharingResult result:resultList) { + wxProfitSharingResultMapper.insertSelective(result); + } + + return new ResultData(returnMap); + } + + @Override @Transactional(isolation=Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) public ResultData createSharingOrder(WxSharingOrderDto sharingOrderDto) { @@ -197,7 +314,8 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ jo.put("type",EnumProfitSharingReceiverType.getEnum(receiver.getReceiverType()).getMessage()); jo.put("account",receiver.getReceiverAccount()); jo.put("amount", receiver.getSharingAmount()); - jo.put("description",receiver.getReceiverComments()); + //jo.put("description",receiver.getReceiverComments()); //改为存ID, + jo.put("description",receiver.getId().toString()); //为重试做准备 receivers.add(jo); WxProfitSharingResult result = new WxProfitSharingResult(); @@ -350,66 +468,68 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ wxProfitSharingOrderMapper.updateByPrimaryKey(record); String receivers = returnMap.get("receivers"); - JSONArray jReceivers = JSONArray.parseArray(receivers); - - WxProfitSharingResult result = new WxProfitSharingResult(); - result.setSharingOrderId(record.getId()); - List wxProfitSharingResultList = wxProfitSharingResultMapper.findList(result); - - for(int j = 0; j < jReceivers.size() ; j++) { - JSONObject res = (JSONObject)jReceivers.get(j); - JSONObject des = new JSONObject(); - des.put("type",res.getString("type")); - des.put("account",res.getString("account")); - des.put("description",res.getString("description")); - des.put("amount",res.getString("amount")); - - int i = 0; - for(i = 0; i wxProfitSharingResultList = wxProfitSharingResultMapper.findList(result); + + for(int j = 0; j < jReceivers.size() ; j++) { + JSONObject res = (JSONObject) jReceivers.get(j); + JSONObject des = new JSONObject(); + des.put("type", res.getString("type")); + des.put("account", res.getString("account")); + des.put("description", res.getString("description")); + des.put("amount", res.getString("amount")); + + int i = 0; + for (i = 0; i < wxProfitSharingResultList.size(); i++) { + WxProfitSharingResult wxProfitSharingResult = wxProfitSharingResultList.get(i); + WxProfitSharingReceiver wxProfitSharingReceiver = wxProfitSharingReceiverMapper + .selectByPrimaryKey(wxProfitSharingResult.getSharingReceiverId()); + if (wxProfitSharingReceiver == null) continue; + + if (res.getString("type").equals(EnumProfitSharingReceiverType.getEnum(wxProfitSharingReceiver.getReceiverType()).getMessage()) + && res.getString("account").equals(wxProfitSharingReceiver.getReceiverAccount())) { + wxProfitSharingResult.setFinishTime(res.getString("finish_time")); + wxProfitSharingResult.setUpdateTime(new Date()); + wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getString("result"))); + wxProfitSharingResult.setFailedReason(res.getString("fail_reason")); + wxProfitSharingResult.setDescription(des.toJSONString()); + wxProfitSharingResultMapper.updateByPrimaryKey(wxProfitSharingResult); + break; + } } - } - if (i == wxProfitSharingResultList.size()){ + if (i == wxProfitSharingResultList.size()) { - WxProfitSharingResult wxProfitSharingResult = new WxProfitSharingResult(); + WxProfitSharingResult wxProfitSharingResult = new WxProfitSharingResult(); - wxProfitSharingResult.setTenantId(record.getTenantId()); - wxProfitSharingResult.setMerchantId(record.getMerchantId()); - wxProfitSharingResult.setSharingOrderId(record.getId()); - wxProfitSharingResult.setSharingReceiverId(0L); //剩余钱分给特约商户,没有相应的接受者 + wxProfitSharingResult.setTenantId(record.getTenantId()); + wxProfitSharingResult.setMerchantId(record.getMerchantId()); + wxProfitSharingResult.setSharingOrderId(record.getId()); + wxProfitSharingResult.setSharingReceiverId(0L); //剩余钱分给特约商户,没有相应的接受者 - List list = wxProfitSharingResultMapper.findList(wxProfitSharingResult); - if (list.size() > 0) { - wxProfitSharingResult = list.get(0); - } + List list = wxProfitSharingResultMapper.findList(wxProfitSharingResult); + if (list.size() > 0) { + wxProfitSharingResult = list.get(0); + } - wxProfitSharingResult.setPayAmount(Integer.valueOf(res.getString("amount"))); - wxProfitSharingResult.setFinishTime(res.getString("finish_time")); - wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getString("result"))); - wxProfitSharingResult.setFailedReason(res.getString("fail_reason")); - wxProfitSharingResult.setDescription(des.toJSONString()); - if (wxProfitSharingResult.getId() != null){ - wxProfitSharingResult.setUpdateTime(new Date()); - wxProfitSharingResultMapper.updateByPrimaryKeySelective(wxProfitSharingResult); - } - else { - wxProfitSharingResult.setCreateTime(new Date()); - wxProfitSharingResult.setUpdateTime(new Date()); - wxProfitSharingResult.setId(IdWorker.get().nextId()); - wxProfitSharingResultMapper.insertSelective(wxProfitSharingResult); + wxProfitSharingResult.setPayAmount(Integer.valueOf(res.getString("amount"))); + wxProfitSharingResult.setFinishTime(res.getString("finish_time")); + wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getString("result"))); + wxProfitSharingResult.setFailedReason(res.getString("fail_reason")); + wxProfitSharingResult.setDescription(des.toJSONString()); + if (wxProfitSharingResult.getId() != null) { + wxProfitSharingResult.setUpdateTime(new Date()); + wxProfitSharingResultMapper.updateByPrimaryKeySelective(wxProfitSharingResult); + } else { + wxProfitSharingResult.setCreateTime(new Date()); + wxProfitSharingResult.setUpdateTime(new Date()); + wxProfitSharingResult.setId(IdWorker.get().nextId()); + wxProfitSharingResultMapper.insertSelective(wxProfitSharingResult); + } } } }