package com.zteits.pay.biz; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.DelayQueue; import javax.annotation.PostConstruct; import org.springframework.stereotype.Service; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.alibaba.fastjson.JSONObject; import com.clouds.common.cache.sys.SysCodeValueCacheUtil; import com.clouds.common.constants.CodeValKindEnum; import com.clouds.common.constants.TimeConstants; import com.clouds.common.redis.RedisCacheUtil; import com.clouds.common.utils.DateUtil; import com.clouds.common.utils.ListCopyUtil; import com.clouds.common.utils.ResultUtils; import com.clouds.common.utils.SequenceUtil; import com.github.pagehelper.PageInfo; import com.zteits.clouds.api.apibase.bean.BizResult; import com.zteits.clouds.api.apibase.bean.PageBean; import com.zteits.clouds.api.apibase.constants.AccountTypeEnum; import com.zteits.clouds.api.apibase.constants.BasicEnum; import com.zteits.clouds.api.apibase.constants.DataStatusEnum; import com.zteits.clouds.api.apibase.constants.ErrorType; import com.zteits.clouds.api.apibase.constants.MSGTempleteEnum; import com.zteits.clouds.api.apibase.constants.MSGTypeEnum; import com.zteits.clouds.api.apibase.constants.OrderStateEnum; import com.zteits.clouds.api.apibase.constants.QeualTypeEnum; import com.zteits.clouds.api.apibase.constants.SequenceTypeEnum; import com.zteits.clouds.api.apibase.exception.BizException; import com.zteits.clouds.api.dto.order.payorder.dto.PayOrderDTO; import com.zteits.clouds.api.dto.order.payorder.param.QueryPayOrderForRltOrderIdRequset; import com.zteits.clouds.api.dto.order.refundorder.param.OrderRefundRqeuest; import com.zteits.clouds.api.dto.pay.AcctPayoutDTO; import com.zteits.clouds.api.dto.pay.AcctPersonDTO; import com.zteits.clouds.api.dto.pay.dto.AcctPersonForStoreCarDTO; import com.zteits.clouds.api.dto.pay.param.*; import com.zteits.clouds.api.dto.rocketmq.order.parkorder.inoutsuccess.InOutParkSuccessMsgVO; import com.zteits.clouds.api.dto.sys.SysCodeValueDTO; import com.zteits.clouds.api.dto.sys.param.SysCodeValueByKindQueryRequest; import com.zteits.clouds.api.service.order.acct.AcctService; import com.zteits.clouds.api.service.order.payorder.query.PubPayOrderQueryService; import com.zteits.clouds.api.service.pay.JPushService; import com.zteits.clouds.api.service.pay.TdCAcctPersonService; import com.zteits.clouds.api.service.pay.TdCAcctSourceService; import com.zteits.clouds.api.service.sys.SysCommonService; import com.zteits.pay.dao.*; import com.zteits.pay.domain.*; import com.zteits.pay.pagepager.PageBeanUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @Service("com.zteits.pay.biz.TdCAcctPersonServiceImpl") public class TdCAcctPersonServiceImpl implements TdCAcctPersonService { private static final Logger logger = LoggerFactory.getLogger(TdCAcctPersonServiceImpl.class); @Autowired private TdCAcctPersonDao tdCAcctPersonDao; @Autowired private SysCommonService sysCommonService; @Autowired private TdCAcctPayoutDao tdCAcctPayoutDao; @Autowired private TdCAcctSourceDao tdCAcctSourceDao; @Autowired private TdCAcctPersonChangeDao tdCAcctPersonChangeDao; @Autowired private PubPayOrderQueryService pubPayOrderQueryService; @Autowired private TdCAcctSourceService tdCAcctSourceService; @Autowired private AcctService acctService; @Autowired private TdCCustPersonDao tdCCustPersonDao; @Autowired private TdCStoreCarDao tdCStoreCarDao; @Autowired private JPushService jPushService; @Autowired private RedisCacheUtil redisCacheUtil; private static BlockingQueue custAcctMsgDelayQueue = new DelayQueue<>(); @Override public BizResult updateAcctPerson(AcctPersonRequest request) { TdCAcctPerson acctPersonDo = new TdCAcctPerson(); BeanUtils.copyProperties(request, acctPersonDo); return new BizResult(tdCAcctPersonDao.updateAcctPerson(acctPersonDo)); } @Override public BizResult saveAcctPerson(AcctPersonRequest request) { TdCAcctPerson acctPersonDo = new TdCAcctPerson(); BeanUtils.copyProperties(request, acctPersonDo); Integer flg = tdCAcctPersonDao.insertAcctPerson(acctPersonDo); return new BizResult(flg > 0 ? true : false); } @Override public BizResult getAcctPerson(AcctPersonRequest acctPersonReq) { AcctPersonDTO dto = new AcctPersonDTO(); TdCAcctPerson tdCAcctPerson = new TdCAcctPerson(); BeanUtils.copyProperties(acctPersonReq, tdCAcctPerson); TdCAcctPerson acctPerson = null; if (tdCAcctPerson.getAcctType().equals(AccountTypeEnum.ACCT_RECHARGE.value())) { QueryAcctPersonByCustIdsAndAcctTypeReq queryAcctPersonByCustIdsAndAcctTypeReq = new QueryAcctPersonByCustIdsAndAcctTypeReq(); List acctTypeList = new ArrayList<>(); acctTypeList.add(AccountTypeEnum.ACCT_RECHARGE.value()); acctTypeList.add(AccountTypeEnum.ACCT_SHARE_BERTH.value()); acctTypeList.add(AccountTypeEnum.ACCT_SEND_RECHARGE.value()); queryAcctPersonByCustIdsAndAcctTypeReq.setAcctTypeList(acctTypeList); queryAcctPersonByCustIdsAndAcctTypeReq.setOrgId(tdCAcctPerson.getOrgId()); queryAcctPersonByCustIdsAndAcctTypeReq.setCustId(tdCAcctPerson.getCustId()); List tdCAcctPersons = tdCAcctPersonDao.queryAcctPersonByCustIdAndAcctType( queryAcctPersonByCustIdsAndAcctTypeReq); BigDecimal acctBalance = new BigDecimal(0); acctPerson = new TdCAcctPerson(); if (org.apache.commons.collections.CollectionUtils.isNotEmpty(tdCAcctPersons)) { for (TdCAcctPerson tdCAcctPersonR : tdCAcctPersons) { if (AccountTypeEnum.ACCT_RECHARGE.value() == tdCAcctPersonR.getAcctType()) { BeanUtils.copyProperties(tdCAcctPersonR, acctPerson); } acctBalance = acctBalance.add(tdCAcctPersonR.getAcctBalance()); } } acctPerson.setAcctBalance(acctBalance); } else { acctPerson = tdCAcctPersonDao.getAcctPerson(tdCAcctPerson); } if (acctPerson != null) { BeanUtils.copyProperties(acctPerson, dto); } if (acctPersonReq.getAcctType() == 3) { //查询押金金额 SysCodeValueByKindQueryRequest requestSys = new SysCodeValueByKindQueryRequest(); requestSys.setSysCode(BasicEnum.SYS_CODE.getValue()); requestSys.setSysCodeKind("RNT_CUST_ACCT_DEPOSIT"); BizResult> bizResult = sysCommonService.querySysCodeValueByKind(requestSys); Integer acctDeposit = 0; if (bizResult.isSuccess()) { if (CollectionUtils.isNotEmpty(bizResult.getData())) { SysCodeValueDTO sysCodeValueDTO = bizResult.getData().get(0); acctDeposit = Integer.valueOf(sysCodeValueDTO.getCodeValueName()); } } if (dto.getDataState() == null) { dto.setAcctBalance(new BigDecimal(acctDeposit)); dto.setDataState(0); } else { if (dto.getDataState() == 0) { dto.setAcctBalance(new BigDecimal(acctDeposit)); } } } return new BizResult(dto); } @Override public BizResult> queryAccountPayFeeForAccount(AccountPayFeeForAccountRequest request) { logger.info("开始查询个人账户入参:custId={}" + request.getCustId()); List dtoList = new ArrayList<>(); dtoList = this.queryAccountPay(dtoList, request, AccountTypeEnum.ACCT_SEND_RECHARGE); return new BizResult<>(dtoList); } /** * 递归查询需要扣除的金额 */ private List queryAccountPay(List dtoList, AccountPayFeeForAccountRequest request, AccountTypeEnum accountTypeEnum) { logger.info("开始查询个人账户入参:custId={}" + request.getCustId()); TdCAcctPerson tdCAcctPersonQ = new TdCAcctPerson(); tdCAcctPersonQ.setCustId(request.getCustId()); tdCAcctPersonQ.setAcctType(accountTypeEnum.value()); tdCAcctPersonQ.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson2 = tdCAcctPersonDao.getAcctPerson(tdCAcctPersonQ); if (tdCAcctPerson2 == null) { tdCAcctPerson2 = new TdCAcctPerson(); tdCAcctPerson2.setAcctBalance(new BigDecimal(0)); } BigDecimal tradeFee = tdCAcctPerson2.getAcctBalance(); if (request.getPayFee().compareTo(new BigDecimal(0)) == 0) { throw new BizException(ErrorType.NOTFUND_PAY_ORDER, "0元无需支付或者重复支付!"); } /**1.判断账户余额是否能支付*/ if (tdCAcctPerson2.getAcctBalance().compareTo(request.getPayFee()) >= 0 && request.getPayFee().compareTo( new BigDecimal(0)) != 0) { /**账户余额可以扣除所有的支付金额*/ AcctPayoutDTO tdCAcctPayout = new AcctPayoutDTO(); tdCAcctPayout.setAcctType(accountTypeEnum.value()); tdCAcctPayout.setTradeFee(request.getPayFee()); dtoList.add(tdCAcctPayout); } else if (tdCAcctPerson2.getAcctBalance().compareTo(new BigDecimal(0)) == 0) { /**2.账户余额为0,在其他账户里面扣除*/ if (accountTypeEnum == AccountTypeEnum.ACCT_SEND_RECHARGE) { dtoList = this.queryAccountPay(dtoList, request, AccountTypeEnum.ACCT_RECHARGE); } else { dtoList = this.queryAccountPay(dtoList, request, AccountTypeEnum.ACCT_SHARE_BERTH); } } else { /**3.在赠送余额扣钱,还在其他账户扣钱*/ //扣除个人账户 BigDecimal payFeeA = request.getPayFee().subtract(tdCAcctPerson2.getAcctBalance()); AcctPayoutDTO tdCAcctPayout = new AcctPayoutDTO(); tdCAcctPayout.setAcctType(accountTypeEnum.value()); tdCAcctPayout.setTradeFee(tradeFee); dtoList.add(tdCAcctPayout); request.setPayFee(payFeeA); /**在其他账户里面扣除*/ if (accountTypeEnum == AccountTypeEnum.ACCT_SEND_RECHARGE) { dtoList = this.queryAccountPay(dtoList, request, AccountTypeEnum.ACCT_RECHARGE); } else { dtoList = this.queryAccountPay(dtoList, request, AccountTypeEnum.ACCT_SHARE_BERTH); } } return dtoList; } @Transactional @Override public BizResult accountPayFeeForAccount(AccountPayFeeForAccountRequest request) { logger.info("开始查询个人账户入参:custId={}" + request.getCustId()); TdCAcctPerson tdCAcctPersonQ = new TdCAcctPerson(); tdCAcctPersonQ.setCustId(request.getCustId()); tdCAcctPersonQ.setAcctType(request.getAcctType()); tdCAcctPersonQ.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson2 = tdCAcctPersonDao.getAcctPerson(tdCAcctPersonQ); if (tdCAcctPerson2.getAcctBalance().compareTo(request.getPayFee()) < 0) { throw new BizException(ErrorType.ACCOUNT_NO_MONEY, "账户余额不足!"); } tdCAcctPerson2.setAcctBalance(tdCAcctPerson2.getAcctBalance().subtract(request.getPayFee())); tdCAcctPerson2.setModfiyDate(new Date()); logger.info("更新账户:" + JSONObject.toJSONString(tdCAcctPerson2)); tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson2); this.insertPayout(request, tdCAcctPerson2, request.getAcctType(), request.getPayFee()); try { Integer acctFeeLessSecond = SysCodeValueCacheUtil.queryCodeValue(CodeValKindEnum.ACCT_FEE_LESS_PUSH_SECOND) == null ? 8 : Integer.parseInt(SysCodeValueCacheUtil.queryCodeValue(CodeValKindEnum.ACCT_FEE_LESS_PUSH_SECOND)); custAcctMsgDelayQueue.put(new CustAcctMsgDelayTask(request.getCustId(), acctFeeLessSecond)); } catch (InterruptedException e) { e.printStackTrace(); } return new BizResult<>(true); } @Override public BizResult accountPayForAccountMaybeNegative(AccountPayFeeForAccountRequest request) { logger.info("开始查询个人账户入参:custId={}" + request.getCustId()); TdCAcctPerson tdCAcctPersonQ = new TdCAcctPerson(); tdCAcctPersonQ.setCustId(request.getCustId()); tdCAcctPersonQ.setAcctType(request.getAcctType()); tdCAcctPersonQ.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson2 = tdCAcctPersonDao.getAcctPerson(tdCAcctPersonQ); tdCAcctPerson2.setAcctBalance(tdCAcctPerson2.getAcctBalance().subtract(request.getPayFee())); tdCAcctPerson2.setModfiyDate(new Date()); logger.info("更新账户:" + JSONObject.toJSONString(tdCAcctPerson2)); tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson2); this.insertPayout(request, tdCAcctPerson2, request.getAcctType(), request.getPayFee()); return new BizResult<>(true); } @Transactional @Override public BizResult accountPayFeeForEmployeeAccount(AccountPayFeeForAccountRequest request) { logger.info("开始查询个人账户入参:custId={}" + request.getCustId()); //先查询该订单是否已经扣除过费用了,保证接口幂等性 final List tdCAcctPayouts = tdCAcctPayoutDao.queryAcctPayOutByOrderId(request.getCustId(), request.getOrderId(), request.getPayOrderType()); if (!CollectionUtils.isEmpty(tdCAcctPayouts)) { TdCAcctPayout tdCAcctPayout = tdCAcctPayouts.get(0); //判断已经支付的金额是否相同 if (tdCAcctPayout.getTradeFee().longValue() == request.getPayFee().longValue()) { logger.info("订单orderId:" + request.getOrderId() + "已经扣除收费员款成功了,直接返回true"); return new BizResult<>(true); } else { logger.error("订单orderId:" + request.getOrderId() + "扣除收费员金额失败,已经扣除的金额不正确"); throw new BizException(ErrorType.PARAM_NOT_VALID, "订单orderId:" + request.getOrderId() + "扣除收费员金额失败,已经扣除的金额不正确", false); } } TdCAcctPerson tdCAcctPerson = new TdCAcctPerson(); tdCAcctPerson.setCustId(request.getCustId()); tdCAcctPerson.setAcctType(AccountTypeEnum.ACCT_EMPLOYEE_RECHARGE.value()); tdCAcctPerson.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson2 = tdCAcctPersonDao.getAcctPerson(tdCAcctPerson); /**判断个人账户余额**/ if (tdCAcctPerson2.getAcctBalance().compareTo(request.getPayFee()) != -1) { /**个人账户余额可以扣除所有的支付金额*/ tdCAcctPerson2.setAcctBalance(tdCAcctPerson2.getAcctBalance().subtract(request.getPayFee())); tdCAcctPerson2.setModfiyDate(new Date()); logger.info("更新个人账户:" + JSONObject.toJSONString(tdCAcctPerson2)); tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson2); this.insertPayout(request, tdCAcctPerson2, AccountTypeEnum.ACCT_EMPLOYEE_RECHARGE.value(), request.getPayFee()); } else { throw new BizException(ErrorType.ACCOUNT_NO_FULL_MONEY, "账户余额不足!"); } return new BizResult(true); } /** * 账户支出 * * @param request * @param tdCAcctPerson * @param */ private AcctPayoutDTO insertPayout(AccountPayFeeForAccountRequest request, TdCAcctPerson tdCAcctPerson, Integer acctType, BigDecimal tradeFee) { TdCAcctPayout acctPayoutDo = new TdCAcctPayout(); acctPayoutDo.setAcctId(tdCAcctPerson.getAcctId()); acctPayoutDo.setCustId(request.getCustId()); acctPayoutDo.setAcctType(acctType); acctPayoutDo.setTradeType(request.getPayOrderType()); acctPayoutDo.setTradeDetialType(request.getPayOrderType()); acctPayoutDo.setTradeFee(tradeFee); acctPayoutDo.setTradeBalance(tdCAcctPerson.getAcctBalance()); acctPayoutDo.setTraderId(request.getCustId()); acctPayoutDo.setTradeTime(new Date()); acctPayoutDo.setRltOrderId(request.getOrderId()); acctPayoutDo.setRltPayorderId(request.getPayOrderId()); acctPayoutDo.setRltOrderType(request.getOrderType() + ""); acctPayoutDo.setDataState(DataStatusEnum.DATA_STATUS_VALID.value()); acctPayoutDo.setCreateDate(new Date()); acctPayoutDo.setModfiyDate(new Date()); acctPayoutDo.setOrgId(request.getOrgId()); Long id = tdCAcctPayoutDao.insertPayout(acctPayoutDo); acctPayoutDo.setId(id); AcctPayoutDTO acctPayoutDTO = new AcctPayoutDTO(); BeanUtils.copyProperties(acctPayoutDo, acctPayoutDTO); return acctPayoutDTO; } @Override @Transactional public BizResult accountRefund(OrderRefundRqeuest orderRefundRqeuest) { Boolean updateFlg = false; logger.info("个人账户退款"); if (orderRefundRqeuest == null || StringUtils.isEmpty(orderRefundRqeuest.getRltPayOrderId())) { throw new BizException(ErrorType.PARAMM_NULL, "payOrderId为空!"); } int insertCount = 1; /**1.查询充值记录*/ TdCAcctSource tdCAcctSource = tdCAcctSourceDao.queryTdCAcctSourceByRltPayorderId( orderRefundRqeuest.getRltPayOrderId()); if (tdCAcctSource == null || StringUtils.isEmpty(tdCAcctSource.getCustId())) { throw new BizException(ErrorType.PARAMM_NULL, "个人custId为空!"); } /**2.查询个人充值账户信息(td_c_acct_person).*/ TdCAcctPerson acctPersonDo = new TdCAcctPerson(); acctPersonDo.setCustId(tdCAcctSource.getCustId()); acctPersonDo.setOrgId(tdCAcctSource.getOrgId()); acctPersonDo.setAcctType(orderRefundRqeuest.getAcctType()); TdCAcctPerson acctPerson = tdCAcctPersonDao.getAcctPerson(acctPersonDo); logger.info("查询到个人账户信息为={}", JSONObject.toJSON(acctPerson)); if (acctPerson != null) { /**3更新个人账户.*/ TdCAcctPerson acctPersonUpdate = new TdCAcctPerson(); acctPersonUpdate.setCustId(acctPerson.getCustId()); acctPersonUpdate.setOrgId(acctPerson.getOrgId()); acctPersonUpdate.setAcctType(acctPerson.getAcctType()); acctPersonUpdate.setAcctBalance( acctPerson.getAcctBalance().subtract(new BigDecimal(orderRefundRqeuest.getRefundTotalFee()))); logger.info("当前个人账户金额=【{}】,本次退款金额为=【{}】,相减后金额为=【{}】", acctPerson.getAcctBalance().longValue(), orderRefundRqeuest.getRefundTotalFee(), acctPersonUpdate.getAcctBalance().longValue()); updateFlg = tdCAcctPersonDao.updateAcctPerson(acctPersonUpdate); logger.info("个人账户更新结果={}", updateFlg); } /**插入一条支出记录.*/ TdCAcctPayout acctPayoutDo = new TdCAcctPayout(); acctPayoutDo.setAcctId(acctPerson.getAcctId()); acctPayoutDo.setAcctType(acctPerson.getAcctType()); acctPayoutDo.setCustId(acctPerson.getCustId()); acctPayoutDo.setTradeType(7); acctPayoutDo.setTradeFee(new BigDecimal(orderRefundRqeuest.getRefundTotalFee())); acctPayoutDo.setTradeBalance( acctPerson.getAcctBalance().subtract(new BigDecimal(orderRefundRqeuest.getRefundTotalFee()))); acctPayoutDo.setTraderId(acctPerson.getCustId()); acctPayoutDo.setTraderName(acctPerson.getAcctName()); acctPayoutDo.setTradeTime(new Date()); acctPayoutDo.setRltPayorderId(orderRefundRqeuest.getRltPayOrderId()); acctPayoutDo.setRltOrderId(orderRefundRqeuest.getRltOrderId()); acctPayoutDo.setRltOrderType(orderRefundRqeuest.getPayOrderType() + ""); acctPayoutDo.setDataState(DataStatusEnum.DATA_STATUS_VALID.value()); acctPayoutDo.setCreateDate(DateUtil.getSysDate()); acctPayoutDo.setModfiyDate(DateUtil.getSysDate()); Long insertNum = tdCAcctPayoutDao.insertPayout(acctPayoutDo); logger.info("车主账户支出记录插入结果={}", insertNum); return new BizResult(insertNum > 0 ? true : false); } @Transactional() @Override public BizResult updateAcctPersonAndAcctSource(UpdateAcctPersonAndAcctSourceRequest request) { InOutParkSuccessMsgVO forInOutParkMsgVO = request.getForInOutParkMsgVO(); List acctPersonList = request.getAcctPersonList(); String psServiceCustId = request.getPsServiceCustId(); //收益账户 AcctPersonDTO acctPersonForShare = new AcctPersonDTO(); //收益冻结账户 AcctPersonDTO acctPersonForShareFrozen = new AcctPersonDTO(); if (!org.springframework.util.CollectionUtils.isEmpty(acctPersonList)) { for (AcctPersonDTO acctPerson : acctPersonList) { if (acctPerson == null) { continue; } if (AccountTypeEnum.ACCT_SHARE_BERTH.value().equals(acctPerson.getAcctType())) { BeanUtils.copyProperties(acctPerson, acctPersonForShare); } if (AccountTypeEnum.ACCT_SHARE_BERTH_FROZEN.value().equals(acctPerson.getAcctType())) { BeanUtils.copyProperties(acctPerson, acctPersonForShareFrozen); } } } /**1.通过订单ID查询支付单*/ QueryPayOrderForRltOrderIdRequset queryPayorderForRltOrderIdReq = new QueryPayOrderForRltOrderIdRequset(); queryPayorderForRltOrderIdReq.setSysCode("zteits-pay"); queryPayorderForRltOrderIdReq.setRltOrderId(forInOutParkMsgVO.getOrderId()); BizResult> bizResult = pubPayOrderQueryService.queryPayOrderForRltOrderId( queryPayorderForRltOrderIdReq); List list = ResultUtils.getBizResultData(bizResult); logger.info("共享车位账户信息={}", JSONObject.toJSON(acctPersonForShare)); if (!org.springframework.util.CollectionUtils.isEmpty(list) && acctPersonForShare != null) { for (PayOrderDTO payOrder : list) { if (payOrder == null || !OrderStateEnum.PAYED.value().equals(payOrder.getPayOrderState())) { continue; } if (QeualTypeEnum.QEUAL_TYPE_1.getValue().equals(payOrder.getQeualType())) {//账已平 //更新前余额=实收 - 平台服务费 this.inserSourceAndupdateFrozenAcct(forInOutParkMsgVO, acctPersonForShare, payOrder); } else if (QeualTypeEnum.QEUAL_TYPE_11.getValue().equals(payOrder.getQeualType())) {//帐未平 if (acctPersonForShareFrozen != null && StringUtils.isNotEmpty( acctPersonForShareFrozen.getCustId())) { /**插入账户流水,更新账户余额*/ this.inserSourceAndupdateFrozenAcct(forInOutParkMsgVO, acctPersonForShareFrozen, payOrder); } else {//插入冻结账户 //更新前余额=实收 - 平台服务费 Long beforActFee = (payOrder.getOrderActFee() == null ? 0L : payOrder.getOrderActFee()) - ( payOrder.getPlatformServiceFee() == null ? 0L : payOrder.getPlatformServiceFee()); /**1.插入冻结账户*/ AcctPersonRequest acctPersonRequest = this.saveAccPerson(payOrder, psServiceCustId); BeanUtils.copyProperties(acctPersonForShare, acctPersonForShare); /**2.插入个人账户流水表 更新账户余额*/ this.inserSourceAndupdateFrozenAcct(forInOutParkMsgVO, acctPersonForShare, payOrder); } } }//for } return new BizResult(true); } @Override public BizResult> queryAcctPersonByCustIdAndAcctType( QueryAcctPersonByCustIdsAndAcctTypeReq request) { List list = new ArrayList<>(); logger.info("begin通过custId 和账户类型查询个人账户信息,入参={}", JSONObject.toJSON(request)); List tdCAcctPersons = tdCAcctPersonDao.queryAcctPersonByCustIdAndAcctType(request); ListCopyUtil.listCopyProperties(tdCAcctPersons, list, AcctPersonDTO.class); logger.info("end通过custId 和账户类型查询个人账户信息"); return new BizResult<>(list); } @Override public BizResult> getAcctPersonGroupByOrgId(QueryAcctPersonByCustIdsAndAcctTypeReq request) { List acctPersonGroupByOrgId = tdCAcctPersonDao.getAcctPersonGroupByOrgId(request); return new BizResult<>(acctPersonGroupByOrgId); } @Override public BizResult> getAcctPersonGroupByAcctType(QueryAcctPersonByCustIdsAndAcctTypeReq request) { List list = new ArrayList<>(); List acctPersonGroupByOrgId = tdCAcctPersonDao.getAcctPersonGroupByAcctType(request); ListCopyUtil.listCopyProperties(acctPersonGroupByOrgId, list, AcctPersonDTO.class); return new BizResult<>(list); } /** * 通过账户 ID 查询个人账户信息 * * @param * @return * @Auther: wangfs */ @Override public BizResult getAcctPersonByAcctId(QueryAcctPersonByAcctIdReq req) { AcctPersonDTO acctPersonDTO = new AcctPersonDTO(); TdCAcctPerson acctPerson = tdCAcctPersonDao.getAcctPersonByAcctIdAndAcctType(req.getAcctId(),req.getAcctType()); BeanUtils.copyProperties(acctPerson, acctPersonDTO); return new BizResult(acctPersonDTO); } /** * 个人账户金额加或者减操作 * * @param * @return * @Auther: wangfs */ @Override @Transactional(rollbackFor = Exception.class) public BizResult addOrsubAcctPersonFeeByAcctId(AddOrsubAcctPersonFeeByAcctIdReq req) { logger.info("begin个人账户金额加或者减操作,入参={}", JSONObject.toJSON(req)); if (req == null && StringUtils.isEmpty(req.getAcctId()) || req.getAddOrSubType() == null || req.getAcctFee() == null) { throw new BizException(ErrorType.PARAMM_NULL, "入参为空,不能对个人账户加减操作!"); } TdCAcctPerson tdCAcctPerson = tdCAcctPersonDao.getAcctPersonByAcctId(req.getAcctId()); if (null == tdCAcctPerson) { throw new BizException(ErrorType.BIZ_ERROR, "账户信息不存在"); } if (req.getAddOrSubType().equals(2)) {//减法操作 /**插入一条支出记录.*/ TdCAcctPayout acctPayoutDo = new TdCAcctPayout(); acctPayoutDo.setAcctId(tdCAcctPerson.getAcctId()); acctPayoutDo.setAcctType(tdCAcctPerson.getAcctType()); acctPayoutDo.setCustId(tdCAcctPerson.getCustId()); acctPayoutDo.setTradeType(7); acctPayoutDo.setTradeFee(new BigDecimal(req.getAcctFee())); acctPayoutDo.setTradeBalance(tdCAcctPerson.getAcctBalance().subtract(new BigDecimal(req.getAcctFee()))); acctPayoutDo.setTraderId(tdCAcctPerson.getCustId()); acctPayoutDo.setTraderName(tdCAcctPerson.getAcctName()); acctPayoutDo.setTradeTime(new Date()); acctPayoutDo.setRltPayorderId(req.getRltPayOrderId()); acctPayoutDo.setRltOrderId(req.getRltOrderId()); acctPayoutDo.setRltOrderType(req.getPayOrderType() + ""); acctPayoutDo.setDataState(DataStatusEnum.DATA_STATUS_VALID.value()); acctPayoutDo.setCreateDate(DateUtil.getSysDate()); acctPayoutDo.setModfiyDate(DateUtil.getSysDate()); acctPayoutDo.setOrgId(tdCAcctPerson.getOrgId()); Long insertNum = tdCAcctPayoutDao.insertPayout(acctPayoutDo); } else {//加法操作 TdCAcctSource acctSource = new TdCAcctSource(); acctSource.setAcctId(tdCAcctPerson.getAcctId()); acctSource.setAcctType(tdCAcctPerson.getAcctType()); acctSource.setCustId(tdCAcctPerson.getCustId()); acctSource.setRechargeType(-5); acctSource.setRechargeFee(new BigDecimal(req.getAcctFee())); acctSource.setRechargeBalance(tdCAcctPerson.getAcctBalance().add(new BigDecimal(req.getAcctFee()))); acctSource.setRechargeRemark("退款"); acctSource.setRechargeId(tdCAcctPerson.getCustId()); acctSource.setRechargeName(tdCAcctPerson.getAcctName()); acctSource.setRechargeTime(new Date()); acctSource.setRltPayorderId(req.getRltPayOrderId()); acctSource.setRltOrderId(req.getRltOrderId()); acctSource.setAcctUptState(1); acctSource.setDataState(DataStatusEnum.DATA_STATUS_VALID.value()); acctSource.setCreateDate(DateUtil.getSysDate()); acctSource.setModfiyDate(DateUtil.getSysDate()); acctSource.setOrgId(tdCAcctPerson.getOrgId()); Integer insertNum = tdCAcctSourceDao.insertAcctSource(acctSource); } Integer updateCount = tdCAcctPersonDao.addOrsubAcctPersonFeeByAcctId(req); logger.info("end个人账户金额加或者减操作,更新条数={}", updateCount); return new BizResult(updateCount); } @Override public BizResult updateAccountEmployeeDefaultFee(AccountRechargeForEmployeeRequest request) { /**修改收费员限制金额*/ /**1.判断限制金额和账户余额是否相等*/ TdCAcctPerson tdCAcctPersonQ = new TdCAcctPerson(); tdCAcctPersonQ.setCustId(request.getCustId()); tdCAcctPersonQ.setAcctType(AccountTypeEnum.ACCT_EMPLOYEE_RECHARGE.value()); tdCAcctPersonQ.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson = tdCAcctPersonDao.getAcctPerson(tdCAcctPersonQ); if(!tdCAcctPerson.getAcctBalance().equals(tdCAcctPerson.getAcctDefaultBalance())){ throw new BizException(ErrorType.ACCOUNT_NOT_EQUAL,"账户余额与账户限制金额不一致,无法修改!"); } /**账户变更赋值*/ TdCAcctPersonChange tdCAcctPersonChange = new TdCAcctPersonChange(); BeanUtils.copyProperties(tdCAcctPerson,tdCAcctPersonChange); /**2.修改账户限制金额*/ tdCAcctPerson.setAcctDefaultBalance(request.getAcctDefaultBalance()); tdCAcctPerson.setAcctBalance(request.getAcctDefaultBalance()); tdCAcctPerson.setModfiyDate(new Date()); tdCAcctPerson.setModfiyEmpid(request.getCreateEmpid()); Boolean flg = tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson); /**3.插入账户变更**/ tdCAcctPersonChange.setModfiyEmpid(request.getCreateEmpid()); tdCAcctPersonChange.setModfiyDate(new Date()); tdCAcctPersonChange.setChangeAcctBalance(request.getAcctDefaultBalance()); tdCAcctPersonChange.setChangeAcctDefaultBalance(request.getAcctDefaultBalance()); tdCAcctPersonChangeDao.saveTdCAcctPersonChange(tdCAcctPersonChange); return new BizResult<>(flg); } @Override public BizResult updateAccountEmployeeDefaultFeeNotJudge(AccountRechargeForEmployeeRequest request) { /**修改收费员限制金额*/ /**1.判断限制金额和账户余额是否相等*/ TdCAcctPerson tdCAcctPersonQ = new TdCAcctPerson(); tdCAcctPersonQ.setCustId(request.getCustId()); tdCAcctPersonQ.setAcctType(AccountTypeEnum.ACCT_EMPLOYEE_RECHARGE.value()); tdCAcctPersonQ.setOrgId(request.getOrgId()); TdCAcctPerson tdCAcctPerson = tdCAcctPersonDao.getAcctPerson(tdCAcctPersonQ); /**账户变更赋值*/ TdCAcctPersonChange tdCAcctPersonChange = new TdCAcctPersonChange(); BeanUtils.copyProperties(tdCAcctPerson,tdCAcctPersonChange); /**2.修改账户限制金额*/ tdCAcctPerson.setAcctDefaultBalance(request.getAcctDefaultBalance()); tdCAcctPerson.setModfiyDate(new Date()); tdCAcctPerson.setModfiyEmpid(request.getCreateEmpid()); Boolean flg = tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson); /**3.插入账户变更**/ tdCAcctPersonChange.setModfiyEmpid(request.getCreateEmpid()); tdCAcctPersonChange.setModfiyDate(new Date()); tdCAcctPersonChange.setChangeAcctBalance(tdCAcctPerson.getAcctBalance()); tdCAcctPersonChange.setChangeAcctDefaultBalance(request.getAcctDefaultBalance()); tdCAcctPersonChangeDao.saveTdCAcctPersonChange(tdCAcctPersonChange); return new BizResult<>(flg); } @Override public BizResult> queryAcctPersonStoreCarForPage(QueryAcctPersonForPageReq request) { PageInfo pageInfo = tdCAcctPersonDao.queryAcctPersonStoreCarForPage(request); PageBean pageBean = new PageBean<>(); PageBeanUtil.copyProperties(pageInfo, pageBean, AcctPersonForStoreCarDTO.class); return new BizResult<>(pageBean); } @Override public BizResult closeStoreCarAccount(AcctPersonRequest req) { /**1、查询储值车账户余额 */ QueryAcctPersonByCustIdsAndAcctTypeReq requestQ = new QueryAcctPersonByCustIdsAndAcctTypeReq(); requestQ.setSysCode(req.getSysCode()); requestQ.setCustId(req.getCustId()); requestQ.setAcctTypeList(Arrays.asList(AccountTypeEnum.ACCT_STORE_CAR.value())); requestQ.setOrgId(req.getOrgId()); List acctPersonDTOList = tdCAcctPersonDao.queryAcctPersonByCustIdAndAcctType(requestQ); if (CollectionUtils.isEmpty(acctPersonDTOList) || acctPersonDTOList.size() > 1) { throw new BizException(ErrorType.BIZ_ERROR, "储值车账户异常"); } TdCAcctPerson tdCAcctPerson = acctPersonDTOList.get(0); //收费员账户余额 BigDecimal balance = tdCAcctPerson.getAcctBalance(); /**2、储值车收入表中 插入一条 负数余额的收入*/ AccountRechargeForEmployeeRequest accountRechargeForEmployeeRequest = new AccountRechargeForEmployeeRequest(); accountRechargeForEmployeeRequest.setSysCode(req.getSysCode()); accountRechargeForEmployeeRequest.setCustId(req.getCustId()); accountRechargeForEmployeeRequest.setCreateEmpid(req.getsOpId().toString()); accountRechargeForEmployeeRequest.setCreateEmpName(req.getsOpName()); accountRechargeForEmployeeRequest.setsOpId(req.getsOpId()); accountRechargeForEmployeeRequest.setsOpName(req.getsOpName()); //更新后账户余额为0 accountRechargeForEmployeeRequest.setRechargeFee(BigDecimal.ZERO.subtract(balance)); accountRechargeForEmployeeRequest.setRechargeRemark("储值车账户销户,余额冲退!"); accountRechargeForEmployeeRequest.setRechargeTime(new Date()); accountRechargeForEmployeeRequest.setOrgId(req.getOrgId()); Boolean flag = ResultUtils.getBizResultData(acctService.accountStoreCarRechargeByXJ(accountRechargeForEmployeeRequest)); if (!flag) { throw new BizException(ErrorType.BIZ_ERROR, "储值车账户余额冲退失败"); } tdCAcctPerson.setAcctBalance(BigDecimal.ZERO); tdCAcctPerson.setDataState(DataStatusEnum.DATA_STATUS_NO_VALID.value()); tdCAcctPerson.setModfiyEmpid(req.getCreateEmpid()); tdCAcctPerson.setModfiyDate(new Date()); tdCAcctPersonDao.updateAcctPerson(tdCAcctPerson); /**3.删除储值车**/ TdCStoreCar record = new TdCStoreCar(); record.setDataState(DataStatusEnum.DATA_STATUS_NO_VALID.value()); TdCStoreCarExample example = new TdCStoreCarExample(); example.createCriteria().andCustIdEqualTo(req.getCustId()) .andOrgIdEqualTo(req.getOrgId()); tdCStoreCarDao.updateByExampleSelective(record,example); return new BizResult<>(true); } private AcctPersonRequest saveAccPerson(PayOrderDTO payOrder, String psServiceCustId) { AcctPersonRequest acctPersonRequest = new AcctPersonRequest(); acctPersonRequest.setAcctId( SequenceUtil.getNextId(SequenceTypeEnum.ACCOUNT_ID_P_SQE)); //账户id acctPersonRequest.setCustId(psServiceCustId); //个人客户id acctPersonRequest.setAcctType( AccountTypeEnum.ACCT_SHARE_BERTH_FROZEN.value()); //账户类型 1、个人现金账户 2、积分账户 3、押金账户、4:收益账户,5:收益冻结账户 acctPersonRequest.setAcctBalance(new BigDecimal(0)); //账户余额 acctPersonRequest.setAcctName("共享车位冻结账户"); //账户名称 acctPersonRequest.setAcctTypeUnit( 1); //单位: 1:分,2:张,3:次,4:小时,5:天,6:个 acctPersonRequest.setMainFlg( 0); //是否是主账户 1:是,0:否 -目前现金账户为主账户 acctPersonRequest.setDataState(DataStatusEnum.DATA_STATUS_FROZEN.value()); //数据状态:1有效,0无效,2 冻结 acctPersonRequest.setCreateEmpid(psServiceCustId); acctPersonRequest.setCreateDate(new Date()); acctPersonRequest.setSysCode("1001"); acctPersonRequest.setOrgId(payOrder.getOrgId()); BizResult saveAcctPerson = this.saveAcctPerson(acctPersonRequest); if (saveAcctPerson == null || !saveAcctPerson.getData()) { throw new BizException(ErrorType.ACCOUNT_NO_FIND, "插入个人共享账失败"); } return acctPersonRequest; } private void inserSourceAndupdateFrozenAcct(InOutParkSuccessMsgVO forInOutParkMsgVO, AcctPersonDTO acctPersonForShare, PayOrderDTO payOrder) { Long beforActFee = (payOrder.getOrderActFee() == null ? 0L : payOrder.getOrderActFee()) - ( payOrder.getPlatformServiceFee() == null ? 0L : payOrder.getPlatformServiceFee()); //账户余额 acctPersonForShare.setAcctBalance( new BigDecimal(acctPersonForShare.getAcctBalance().longValue() + beforActFee)); /**2.插入个人账户流水表*/ AcctSourceRequest acctSourceRequest = new AcctSourceRequest(); acctSourceRequest.setAcctId(acctPersonForShare.getAcctId()); //账户id acctSourceRequest.setCustId(acctPersonForShare.getCustId());//个人客户id acctSourceRequest.setAcctType(acctPersonForShare.getAcctType());//个人客户 账户类型 acctSourceRequest.setRechargeType( payOrder.getPayType()); //1:支付宝 2:微信 3:银联 4:微信公众号 5 个人账户 6:现金 7:IC卡 acctSourceRequest.setPlNo(forInOutParkMsgVO.getPlNo()); //停车场编码 acctSourceRequest.setBerthNo(forInOutParkMsgVO.getBerthNo()); //车位编码 acctSourceRequest.setRechargeFee(new BigDecimal(beforActFee)); //充值金额 acctSourceRequest.setRechargeBalance(acctPersonForShare.getAcctBalance()); //充值后余额 acctSourceRequest.setRechargeId(payOrder.getCreateEmpId()); //充值人id acctSourceRequest.setRechargeName(payOrder.getCreateEmpName()); //充值人姓名 acctSourceRequest.setRechargeTime(new Date()); //充值时间 acctSourceRequest.setRltPayorderId(payOrder.getPayOrderId()); //对应的支付单id acctSourceRequest.setRltOrderId(payOrder.getRltOrderId()); //订单id acctSourceRequest.setQeualType( payOrder.getQeualType()); //平账类型 -1:帐未平, 0:未开始平账 1:账已平 acctSourceRequest.setRntServiceFee(new BigDecimal(payOrder.getPlatformServiceFee())); //平台服务费 acctSourceRequest.setDataState(DataStatusEnum.DATA_STATUS_VALID.value()); //数据状态 acctSourceRequest.setAcctUptState(1); acctSourceRequest.setCreateEmpid(payOrder.getCreateEmpId()); acctSourceRequest.setCreateDate(new Date()); acctSourceRequest.setSysCode("1001"); acctSourceRequest.setOrgId(acctSourceRequest.getOrgId()); BizResult insertAcctSource = tdCAcctSourceService.insertAcctSource(acctSourceRequest); if (insertAcctSource == null || !insertAcctSource.getData()) { throw new BizException(ErrorType.ACCOUNT_NO_FIND, "插入个人账户流水表失败"); } /**2.更新个人共享账户*/ AcctPersonRequest acctPersonRequest = new AcctPersonRequest(); BeanUtils.copyProperties(acctPersonForShare, acctPersonRequest); acctPersonRequest.setSysCode("1001"); BizResult updateAcctPerson = this.updateAcctPerson(acctPersonRequest); if (updateAcctPerson == null || !updateAcctPerson.getData()) { throw new BizException(ErrorType.ACCOUNT_NO_FIND, "更新个人共享账失败"); } } @PostConstruct public void handleCustAcctMsgDelayTask() { new Thread(()-> { Integer acctFeeLessNum = SysCodeValueCacheUtil.queryCodeValue(CodeValKindEnum.ACCT_FEE_LESS_PUSH_NUM) == null ? 500 : Integer.parseInt(SysCodeValueCacheUtil.queryCodeValue(CodeValKindEnum.ACCT_FEE_LESS_PUSH_NUM)); for(;;) { try { String custId = custAcctMsgDelayQueue.take().getCustId(); TdCCustPerson tdCCustPerson = tdCCustPersonDao.queryPersonByCustId(custId); if(tdCCustPerson.getOrgId() == null || !tdCCustPerson.getOrgId().equals(10003L)){ continue; } QueryAcctPersonByCustIdsAndAcctTypeReq queryAcctPersonByCustIdsAndAcctTypeReq = new QueryAcctPersonByCustIdsAndAcctTypeReq(); List acctTypeList = new ArrayList<>(); acctTypeList.add(AccountTypeEnum.ACCT_RECHARGE.value()); acctTypeList.add(AccountTypeEnum.ACCT_SHARE_BERTH.value()); acctTypeList.add(AccountTypeEnum.ACCT_SEND_RECHARGE.value()); acctTypeList.add(AccountTypeEnum.ACCT_CASH_COUPON.value()); queryAcctPersonByCustIdsAndAcctTypeReq.setAcctTypeList(acctTypeList); queryAcctPersonByCustIdsAndAcctTypeReq.setCustId(custId); queryAcctPersonByCustIdsAndAcctTypeReq.setOrgId(10003L); queryAcctPersonByCustIdsAndAcctTypeReq.setSysCode(BasicEnum.SYS_CODE.getValue()); List acctPersons = tdCAcctPersonDao.getAcctPersonGroupByOrgId(queryAcctPersonByCustIdsAndAcctTypeReq); if(acctPersons == null || acctPersons.size() == 0){ logger.info("custId={},无账号信息",custId); continue; } BigDecimal acctBalance = acctPersons.get(0).getAcctBalance(); if(acctBalance.compareTo(new BigDecimal(acctFeeLessNum)) >= 0){ logger.info("custId={},余额到推送阈值",custId); continue; } Boolean pushFlag = redisCacheUtil.checkPushLock(custId, TimeConstants.SECOND_1_DAY); if(!pushFlag){ logger.info("custId={},24小时内已推送",custId); continue; } JPushMessageRequest request = new JPushMessageRequest(); request.setCustId(custId); request.setTempleteId(MSGTempleteEnum.APP_ACCT_FEE_LESS.value()); request.setMsgType(MSGTypeEnum.MSG_TYPE_SYS.value()); request.setPushType(MSGTypeEnum.MSG_PUSH_TYPE_ONLY.value()); request.setReturnType(MSGTypeEnum.MSG_RETURN_YES.value()); request.setSysCode((BasicEnum.SYS_CODE.getValue())); jPushService.sendAcctBalanceLessPush(request); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }