| @@ -39,7 +39,9 @@ public enum EnumFlowKey { | |||
| SETTLE(21,"结算单审批"), | |||
| BILL_FINISH(30,"商户账单完结审批"), | |||
| CASH_OUT(23,"商户提现审批") | |||
| CASH_OUT(23,"商户提现审批"), | |||
| CARD_ORDER_REFUND(31,"商户提现审批") | |||
| ; | |||
| public static EnumFlowKey getEnum(Integer code) { | |||
| @@ -16,4 +16,10 @@ public interface WxCardInfoMapper extends CommonMapper<WxCardInfo, Long> { | |||
| void updateStatus(WxCardInfo wxCardInfo); | |||
| /** | |||
| * 修改面额 | |||
| * @param cardInfo | |||
| * @return | |||
| */ | |||
| int updAmount(WxCardInfo cardInfo); | |||
| } | |||
| @@ -57,4 +57,13 @@ public interface WxCardInfoService { | |||
| PageInfo<WxCardTransferVo> listTransferAsPage(WxCardTransferInfo transferRecord, Integer pageIndex, Integer pageSize); | |||
| /** | |||
| * | |||
| * @param cardInfo | |||
| * @param amount 总面额变动值 | |||
| * @param remainingAmount 剩余面额变动值 | |||
| * @param remainingShareFeeAmount 分账余额变动值 | |||
| */ | |||
| void updAmount(WxCardInfo cardInfo,Integer amount,Integer remainingAmount,Integer remainingShareFeeAmount); | |||
| } | |||
| @@ -34,6 +34,8 @@ public interface WxCardSpendService { | |||
| */ | |||
| ResultData createCardSpend(WxCardSpend record, WxOrder order, WxCouponMerchant couponMerchant); | |||
| void sendCardBalanceChange(WxCoupon coupon,WxCardSpend cardSpend); | |||
| /** | |||
| * 根据实体查询分页列表 | |||
| * | |||
| @@ -118,6 +118,6 @@ public interface WxRefundOrderService { | |||
| ResultData refundCardOrderSuccess(WxRefundOrder refundOrder,WxOrder wxOrder); | |||
| ResultData refundCardOrderFail(WxRefundOrder refundOrder,WxOrder wxOrder); | |||
| ResultData refundCardOrderFail(WxRefundOrder refundOrder,WxOrder wxOrder,String remark); | |||
| } | |||
| @@ -41,6 +41,8 @@ import com.iformall.utils.Constant; | |||
| import com.iformall.utils.RedisLock; | |||
| import org.apache.commons.beanutils.BeanUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.context.annotation.Lazy; | |||
| import org.springframework.stereotype.Service; | |||
| @@ -60,6 +62,8 @@ import java.util.Map; | |||
| @Service | |||
| public class WxCardInfoServiceImpl implements WxCardInfoService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| WxCardInfoMapper wxCardInfoMapper; | |||
| @@ -389,8 +393,37 @@ public class WxCardInfoServiceImpl implements WxCardInfoService { | |||
| pageInfo.setTotal(cardInfoPage.getTotal()); | |||
| return pageInfo; | |||
| } | |||
| private List<WxCardTransferVo> toTransferVoList(List<WxCardTransferInfo> transferList,TenantEntity tenantEntity) { | |||
| @Override | |||
| public void updAmount(WxCardInfo cardInfo,Integer amount,Integer remainingAmount,Integer remainingShareFeeAmount) { | |||
| //此处需要加锁,防止并发设置 | |||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||
| String timeStr = String.valueOf(time); | |||
| boolean cashsetlock = redisLock.lock("cardInfoLockAmountSet_"+cardInfo.getId(), timeStr); | |||
| if (cashsetlock) { | |||
| try { | |||
| WxCardInfo cardInfoUpd = new WxCardInfo(); | |||
| cardInfoUpd.setId(cardInfo.getId()); | |||
| cardInfoUpd.updateTenantInfo(cardInfo); | |||
| cardInfoUpd.setAmount(amount); | |||
| cardInfoUpd.setRemainingAmount(remainingAmount); | |||
| cardInfoUpd.setRemainingShareFeeAmount(remainingShareFeeAmount); | |||
| int i = wxCardInfoMapper.updAmount(cardInfo); | |||
| redisLock.unlock("cardInfoLockAmountSet_"+cardInfo.getId(), timeStr); | |||
| if(i != 1){ | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"卡余额不足 error."); | |||
| } | |||
| }catch(Exception e) { | |||
| redisLock.unlock("cardInfoLockAmountSet_"+cardInfo.getId(), timeStr); | |||
| logger.error("updAmount error."+cardInfo.getId(),e); | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"余额变动 error."+e.getMessage()); | |||
| }finally { | |||
| redisLock.unlock("cardInfoLockAmountSet_"+cardInfo.getId(), timeStr); | |||
| } | |||
| } | |||
| } | |||
| private List<WxCardTransferVo> toTransferVoList(List<WxCardTransferInfo> transferList,TenantEntity tenantEntity) { | |||
| List<WxCardTransferVo> retList = new ArrayList<WxCardTransferVo>(); | |||
| if (null != transferList && transferList.size() > 0 ) { | |||
| List<Long> userList = new ArrayList<>(); | |||
| @@ -54,6 +54,9 @@ public class WxCardSpendServiceImpl implements WxCardSpendService { | |||
| @Autowired | |||
| WxCardSpendMapper wxCardSpendMapper; | |||
| @Autowired | |||
| WxCardInfoService wxCardInfoService; | |||
| @Autowired | |||
| WxCardInfoMapper wxCardInfoMapper; | |||
| @@ -211,25 +214,11 @@ public class WxCardSpendServiceImpl implements WxCardSpendService { | |||
| } | |||
| // 7. update card info | |||
| WxCardInfo updateCardInfo = new WxCardInfo(); | |||
| updateCardInfo.setId(cardInfo.getId()); | |||
| updateCardInfo.setRemainingAmount(remaingAmount); | |||
| updateCardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||
| updateCardInfo.setUpdateDate(curDate); | |||
| wxCardInfoService.updAmount(cardInfo,null,0-record.getDeductionAmount(),0-real_payment); | |||
| cardInfo.setRemainingAmount(remaingAmount); | |||
| cardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||
| cardInfo.setUpdateDate(curDate); | |||
| // 7.1、消费后修改卡转赠状态 | |||
| // if (cardInfo.getSupportTransfer().equals(EnumCouponTransfer.YES.getCode())) { | |||
| // updateCardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); | |||
| // cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode()); | |||
| // } | |||
| try { | |||
| wxCardInfoMapper.updateById(updateCardInfo); | |||
| } catch (Exception e) { | |||
| logger.error("card info update error"); | |||
| return new ResultData(ErrorCode.DB_FAIL.getCode(), "card info 更新出错!"); | |||
| } | |||
| // 7.2 update coupon card status | |||
| if (cardInfo.getRemainingAmount().equals(0)) { | |||
| @@ -355,11 +344,13 @@ public class WxCardSpendServiceImpl implements WxCardSpendService { | |||
| /** | |||
| * 卡余额变动订阅消息 | |||
| */ | |||
| private void sendCardBalanceChange(WxCoupon coupon,WxCardSpend cardSpend){ | |||
| @Override | |||
| public void sendCardBalanceChange(WxCoupon coupon,WxCardSpend cardSpend){ | |||
| try { | |||
| if(cardSpend.getOwnerId() == null){ | |||
| return; | |||
| } | |||
| WxCUser wcuQ = new WxCUser(); | |||
| wcuQ.updateTenantInfo(coupon); | |||
| wcuQ.setUserId(cardSpend.getOwnerId()); | |||
| @@ -97,6 +97,8 @@ public class WxFlowServiceImpl implements WxFlowService { | |||
| @Autowired | |||
| private WxBillSettleService wxBillSettleService; | |||
| @Autowired | |||
| private WxRefundOrderService wxRefundOrderService; | |||
| @Autowired | |||
| @Qualifier("couponChannelRedisTemplate") | |||
| RedisTemplate<String, PageInfo<WxCouponChannelVo>> cdRedisTemplate; | |||
| @Autowired | |||
| @@ -467,7 +469,6 @@ public class WxFlowServiceImpl implements WxFlowService { | |||
| }else if (EnumFlowKey.CASH_OUT.getCode().equals(flowType)) { | |||
| String tenantId = (String)getVariableByKey(variables,"cashTenantId"); | |||
| WxCashOut cashout = wxCashOutService.getById(Long.parseLong(businessId), tenantId); | |||
| //如果是提交审批 | |||
| if (EnumRentContractAppStatus.APPLYING.getCode().intValue() == applyStatus.intValue()) { | |||
| cashout.setStatus(EnumCashOutStatus.AUDIOING.getCode()); | |||
| @@ -492,6 +493,17 @@ public class WxFlowServiceImpl implements WxFlowService { | |||
| cashout.setUpdateDate(new Date()); | |||
| wxCashOutService.rejectCashOut(cashout); | |||
| } | |||
| }else if(EnumFlowKey.CARD_ORDER_REFUND.getCode().equals(flowType)){ | |||
| WxRefundOrder RefundOrder = wxRefundOrderService.getById(Long.parseLong(businessId)); | |||
| // 审批完成 | |||
| if (EnumRentContractAppStatus.FINISH.getCode().intValue() == applyStatus.intValue()) { | |||
| wxRefundOrderService.refundCardOrderSuccess(RefundOrder,null); | |||
| //如果是审批撤回,或者驳回,改回草稿状态 | |||
| }else if (EnumRentContractAppStatus.SETBACK.getCode().intValue() == applyStatus.intValue() | |||
| || EnumRentContractAppStatus.REJECT.getCode().intValue() == applyStatus.intValue()) { | |||
| String remark = (String)mapInfo.get("remark"); | |||
| wxRefundOrderService.refundCardOrderFail(RefundOrder,null,remark); | |||
| } | |||
| } | |||
| } | |||
| @@ -88,9 +88,6 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| @Autowired | |||
| WxCUserMapper wxCUserMapper; | |||
| @Autowired | |||
| WxCardInfoMapper cardInfoMapper; | |||
| @Autowired | |||
| PayServiceFactory payServiceFactory; | |||
| @@ -98,6 +95,9 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| @Autowired | |||
| WxBatchOrderMapper wxBatchOrderMapper; | |||
| @Autowired | |||
| WxCardInfoService wxCardInfoService; | |||
| @Autowired | |||
| WxCardInfoMapper wxCardInfoMapper; | |||
| @@ -107,9 +107,15 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| @Autowired | |||
| WxMerchantSubsidyMapper wxMerchantSubsidyMapper; | |||
| @Autowired | |||
| WxCashOutService wxCashOutService; | |||
| @Autowired | |||
| private MqBaseProducer mqBaseProducer; | |||
| @Autowired | |||
| WxFlowService wxFlowService; | |||
| private boolean isMerchantOrder(WxOrder wxOrder, Long merchantId) { | |||
| if (wxOrder.getType().equals(EnumOrderType.COUPON.getCode())) { | |||
| @@ -314,7 +320,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| updateCardInfo.setId(wxCouponOrder.getId()); | |||
| updateCardInfo.setRemainingAmount(0); | |||
| try { | |||
| cardInfoMapper.updateById(updateCardInfo); | |||
| wxCardInfoMapper.updateById(updateCardInfo); | |||
| } catch (Exception e) { | |||
| logger.error("db failed: wxCardInfo-" + wxCouponOrder.getId() + ", e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| @@ -954,7 +960,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| updateCardInfo.setId(wxCouponOrder.getId()); | |||
| updateCardInfo.setRemainingAmount(0); | |||
| try { | |||
| cardInfoMapper.updateById(updateCardInfo); | |||
| wxCardInfoMapper.updateById(updateCardInfo); | |||
| } catch (Exception e) { | |||
| logger.error("db failed: wxCardInfo-" + wxCouponOrder.getId() + ", e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| @@ -1186,11 +1192,20 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| try { | |||
| wxCardSpendMapper.updateById(cardSpendUpd); | |||
| } catch (Exception e) { | |||
| logger.error("卡退款订单修改出错: " + record.toString()); | |||
| logger.error("卡退款订单修改出错: " + cardSpendUpd.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| refundCardOrderSuccess(record,wxOrder); | |||
| boolean hasAudit = hasWorkFlow(cardSend); | |||
| if(hasAudit){ | |||
| Map<String, Object> map = new HashMap<String, Object>(); | |||
| map.put("businessId", String.valueOf(record.getId())); | |||
| map.put("businessType", EnumFlowKey.CARD_ORDER_REFUND.getCode()); | |||
| map.put("phone", bUser.getPhone()); | |||
| wxFlowService.start(map, bUser.getId(), bUser.getName(), bUser); | |||
| return new ResultData(Result.SUCCESS,"提交审批成功"); | |||
| }else{ | |||
| refundCardOrderSuccess(record,wxOrder); | |||
| } | |||
| return new ResultData(); | |||
| } | |||
| @@ -1209,6 +1224,19 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| logger.error("card not found: " + cardSend.getCardId()); | |||
| throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND); | |||
| } | |||
| if(wxOrder == null){ | |||
| wxOrder = wxOrderMapper.selectById(refundOrder.getOrderId(),refundOrder.getTenantId()); | |||
| if (wxOrder == null) { | |||
| logger.error("交易订单不存在:" + cardSend.getOrderId()); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); | |||
| } | |||
| } | |||
| WxCoupon coupon = wxCouponMapper.selectById(cardInfo.getCouponId(),cardInfo.getTenantId()); | |||
| if (coupon == null) { | |||
| logger.error("card's coupon not found: " + cardInfo.getCouponId()); | |||
| throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND); | |||
| } | |||
| Date currentDate = new Date(); | |||
| @@ -1291,23 +1319,12 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| wxCardInfoService.updAmount(cardInfo,null,record.getDeductionAmount(),real_refund); | |||
| WxCardInfo updateCardInfo = new WxCardInfo(); | |||
| updateCardInfo.setId(cardInfo.getId()); | |||
| updateCardInfo.setRemainingAmount(remaingAmount); | |||
| updateCardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||
| updateCardInfo.setUpdateDate(currentDate); | |||
| cardInfo.setRemainingAmount(remaingAmount); | |||
| cardInfo.setRemainingShareFeeAmount(remain_real_pament); | |||
| cardInfo.setUpdateDate(currentDate); | |||
| try { | |||
| wxCardInfoMapper.updateById(updateCardInfo); | |||
| } catch (Exception e) { | |||
| logger.error("card info update error"); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "card info 更新出错!"); | |||
| } | |||
| if(record.getCardBeforeAmount().equals(0)){ | |||
| if (wxCardSpendService.cardFinishedUsing(currentDate, cardInfo)) { | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "couponOrder status 更新出错!"); | |||
| @@ -1376,6 +1393,11 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| merchantSubsidy.setSource(EnumMerchantSubsidySource.CARD.getCode()); | |||
| merchantSubsidy.setStatus(EnumMerchantSubsidyStatus.NOT_SUBSIDY.getCode()); | |||
| wxMerchantSubsidyMapper.insert(merchantSubsidy); | |||
| //更新商户余额 | |||
| Long merchantId = cardSend.getMerchantId(); | |||
| WxMerchant merchant = wxMerchantMapper.selectById(merchantId); | |||
| wxCashOutService.addCashOut(merchant, 0-refund); | |||
| } | |||
| try { | |||
| @@ -1386,13 +1408,14 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "card spend 插入出错!"); | |||
| } | |||
| wxCardSpendService.sendCardBalanceChange(coupon,record); | |||
| return new ResultData(); | |||
| } | |||
| @Override | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public ResultData refundCardOrderFail(WxRefundOrder refundOrder, WxOrder wxOrder) { | |||
| public ResultData refundCardOrderFail(WxRefundOrder refundOrder, WxOrder wxOrder,String remark) { | |||
| Long cardSpendId = Long.parseLong(refundOrder.getPayOrderNo()); | |||
| WxCardSpend cardSend = wxCardSpendMapper.selectById(cardSpendId); | |||
| if(cardSend == null){ | |||
| @@ -1404,15 +1427,22 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| logger.error("card not found: " + cardSend.getCardId()); | |||
| throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND); | |||
| } | |||
| if(wxOrder == null){ | |||
| wxOrder = wxOrderMapper.selectById(refundOrder.getOrderId(),refundOrder.getTenantId()); | |||
| if (wxOrder == null) { | |||
| logger.error("交易订单不存在:" + cardSend.getOrderId()); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); | |||
| } | |||
| } | |||
| Date currentDate = new Date(); | |||
| WxRefundOrder updateOrder = new WxRefundOrder(); | |||
| updateOrder.setId(refundOrder.getId()); | |||
| updateOrder.setOrderId(refundOrder.getOrderId()); | |||
| updateOrder.setUpdateTime(currentDate); | |||
| updateOrder.setRefundOrderStatus(EnumRefundStatus.REFUND_FAIL.getCode()); | |||
| updateOrder.setFailReason(remark); | |||
| // updateOrder.setTransactionId(transactionId); | |||
| // updateOrder.setRefundId(record.getId().toString()); | |||
| // 修改退款订单状态 | |||
| @@ -1450,5 +1480,14 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||
| return new ResultData(); | |||
| } | |||
| protected boolean hasWorkFlow(TenantEntity tenantEntity) { | |||
| WxFlowModel wxFlowModel = new WxFlowModel(); | |||
| wxFlowModel.setFlowType(EnumFlowKey.CARD_ORDER_REFUND.getCode()); | |||
| wxFlowModel.updateTenantInfo(tenantEntity); | |||
| List<WxFlowModel> flows = wxFlowService.getModelBybusiness(wxFlowModel); | |||
| if (null != flows && flows.size() > 0) { | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -151,5 +151,21 @@ | |||
| <update id="updateStatus" parameterType="com.iformall.domain.po.WxCardInfo"> | |||
| update wx_card_info set status=#{status},update_date=now() where id=#{id} and tenant_id = #{tenantId} | |||
| </update> | |||
| <update id="updAmount" parameterType="com.iformall.domain.po.WxCardInfo"> | |||
| update wx_card_info set | |||
| <if test=" null != amount "> | |||
| `amount` = amount+#{amount}, | |||
| </if> | |||
| <if test=" null != remainingAmount "> | |||
| `remaining_amount` = remaining_amount+#{remainingAmount}, | |||
| </if> | |||
| <if test=" null != remainingShareFeeAmount "> | |||
| `remaining_share_fee_amount` = remaining_share_fee_amount+#{remainingShareFeeAmount}, | |||
| </if> | |||
| ,update_date=now() | |||
| where id=#{id} and tenant_id = #{tenantId} | |||
| and remaining_amount+#{remainingAmount} >= 0 | |||
| </update> | |||
| </mapper> | |||