package com.doumee.service.business.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.doumee.core.constants.ResponseStatus;
|
import com.doumee.core.exception.BusinessException;
|
import com.doumee.core.model.LoginUserInfo;
|
import com.doumee.core.utils.Constants;
|
import com.doumee.core.wx.WxJsapiPayUtil;
|
import com.doumee.dao.business.*;
|
import com.doumee.dao.business.dto.YwCustomerRechargeConditionerDTO;
|
import com.doumee.dao.business.dto.YwCustomerRechargeElectricalDTO;
|
import com.doumee.dao.business.dto.h5.CustomerPayCreateDTO;
|
import com.doumee.dao.business.model.*;
|
import com.doumee.service.business.YwContractRevenueService;
|
import com.doumee.service.business.YwCustomerH5BizService;
|
import com.doumee.service.business.YwCustomerRechargeBizService;
|
import com.doumee.service.business.YwCustomerWxPayService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
|
@Service
|
@Slf4j
|
public class YwCustomerWxPayServiceImpl implements YwCustomerWxPayService {
|
|
@Autowired
|
private YwWxPayOrderMapper ywWxPayOrderMapper;
|
@Autowired
|
private YwContractBillMapper ywContractBillMapper;
|
@Autowired
|
private YwContractMapper ywContractMapper;
|
@Autowired
|
private YwAccountMapper ywAccountMapper;
|
@Autowired
|
private YwElectricalChargeMapper ywElectricalChargeMapper;
|
@Autowired
|
private WxJsapiPayUtil wxJsapiPayUtil;
|
@Autowired
|
private YwCustomerRechargeBizService ywCustomerRechargeBizService;
|
@Autowired
|
private YwContractRevenueService ywContractRevenueService;
|
@Autowired
|
private YwCustomerH5BizService ywCustomerH5BizService;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Map<String, String> createOrder(CustomerPayCreateDTO dto, LoginUserInfo user, String clientIp) {
|
if (user == null || user.getCustomerId() == null) {
|
throw new BusinessException(ResponseStatus.NO_ALLOW_LOGIN);
|
}
|
if (dto.getAmount() == null || dto.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
|
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "金额须大于0");
|
}
|
if (StringUtils.isBlank(dto.getOpenid())) {
|
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "openid不能为空");
|
}
|
Integer orderType = dto.getOrderType();
|
Integer bizRefId = resolveBizRefId(dto, user.getCustomerId());
|
validateBiz(orderType, bizRefId, user.getCustomerId(), dto.getAmount());
|
|
String orderNo = "WX" + System.currentTimeMillis() + user.getCustomerId() + new Random().nextInt(1000);
|
YwWxPayOrder order = new YwWxPayOrder();
|
order.setCreator(user.getId());
|
order.setCreateDate(new Date());
|
order.setEditor(user.getId());
|
order.setEditDate(new Date());
|
order.setIsdeleted(Constants.ZERO);
|
order.setOrderNo(orderNo);
|
order.setCustomerId(user.getCustomerId());
|
order.setOrderType(orderType);
|
order.setBizRefId(bizRefId);
|
order.setAmount(dto.getAmount());
|
order.setStatus(YwWxPayOrder.STATUS_WAIT);
|
order.setOpenid(dto.getOpenid());
|
order.setRemark(dto.getRemark());
|
order.setRequestSnapshot(JSON.toJSONString(dto));
|
ywWxPayOrderMapper.insert(order);
|
|
String body = orderType == YwWxPayOrder.TYPE_BILL ? "账单缴费" :
|
(orderType == YwWxPayOrder.TYPE_CONDITIONER ? "空调充值" : "电费充值");
|
Map<String, String> payParams = wxJsapiPayUtil.createJsapiOrder(orderNo, dto.getOpenid(), body, dto.getAmount(), clientIp);
|
payParams.put("orderNo", orderNo);
|
return payParams;
|
}
|
|
@Override
|
public YwWxPayOrder queryOrder(String orderNo, Integer customerId) {
|
return ywWxPayOrderMapper.selectOne(new QueryWrapper<YwWxPayOrder>().lambda()
|
.eq(YwWxPayOrder::getOrderNo, orderNo)
|
.eq(YwWxPayOrder::getCustomerId, customerId)
|
.eq(YwWxPayOrder::getIsdeleted, Constants.ZERO)
|
.last("limit 1"));
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public String handleNotify(String xmlBody) {
|
Map<String, String> data = wxJsapiPayUtil.parseNotifyXml(xmlBody);
|
if (!wxJsapiPayUtil.verifyNotifySign(data)) {
|
return failXml("签名失败");
|
}
|
if (!"SUCCESS".equals(data.get("return_code")) || !"SUCCESS".equals(data.get("result_code"))) {
|
return successXml();
|
}
|
String orderNo = data.get("out_trade_no");
|
YwWxPayOrder order = ywWxPayOrderMapper.selectOne(new QueryWrapper<YwWxPayOrder>().lambda()
|
.eq(YwWxPayOrder::getOrderNo, orderNo)
|
.eq(YwWxPayOrder::getIsdeleted, Constants.ZERO)
|
.last("limit 1"));
|
if (order == null) {
|
return successXml();
|
}
|
if (Objects.equals(order.getStatus(), YwWxPayOrder.STATUS_SUCCESS)) {
|
return successXml();
|
}
|
LoginUserInfo user = buildCustomerUser(order.getCustomerId());
|
try {
|
Integer bizRecordId = fulfillBiz(order, user);
|
order.setStatus(YwWxPayOrder.STATUS_SUCCESS);
|
order.setWxTransactionId(data.get("transaction_id"));
|
order.setPayTime(new Date());
|
order.setBizRecordId(bizRecordId);
|
order.setEditDate(new Date());
|
ywWxPayOrderMapper.updateById(order);
|
} catch (Exception e) {
|
log.error("wx pay fulfill failed orderNo={}", orderNo, e);
|
order.setStatus(YwWxPayOrder.STATUS_FAIL);
|
order.setStatusInfo(e.getMessage());
|
order.setEditDate(new Date());
|
ywWxPayOrderMapper.updateById(order);
|
}
|
return successXml();
|
}
|
|
private Integer fulfillBiz(YwWxPayOrder order, LoginUserInfo user) {
|
CustomerPayCreateDTO dto = JSON.parseObject(order.getRequestSnapshot(), CustomerPayCreateDTO.class);
|
if (order.getOrderType() == YwWxPayOrder.TYPE_BILL) {
|
return createBillRevenue(order, user);
|
}
|
ywCustomerH5BizService.applyFirstRechargeIfNeeded(order.getCustomerId(), user);
|
if (order.getOrderType() == YwWxPayOrder.TYPE_ELECTRICAL) {
|
YwCustomerRechargeElectricalDTO req = new YwCustomerRechargeElectricalDTO();
|
req.setCustomerId(order.getCustomerId());
|
req.setElectricalId(order.getBizRefId());
|
req.setMoney(order.getAmount());
|
req.setRemark(StringUtils.defaultIfBlank(dto != null ? dto.getRemark() : null, "微信H5充值"));
|
ywCustomerRechargeBizService.rechargeElectrical(req, user);
|
return findLatestChargeId(order.getCustomerId(), Constants.ZERO, order.getBizRefId(), order.getOrderNo());
|
}
|
YwCustomerRechargeConditionerDTO req = new YwCustomerRechargeConditionerDTO();
|
req.setCustomerId(order.getCustomerId());
|
req.setMoney(order.getAmount());
|
req.setRemark(StringUtils.defaultIfBlank(dto != null ? dto.getRemark() : null, "微信H5充值"));
|
ywCustomerRechargeBizService.rechargeConditioner(req, user);
|
return findLatestChargeId(order.getCustomerId(), Constants.ONE, order.getCustomerId(), order.getOrderNo());
|
}
|
|
private Integer createBillRevenue(YwWxPayOrder order, LoginUserInfo user) {
|
YwContractBill bill = ywContractBillMapper.selectById(order.getBizRefId());
|
if (bill == null) {
|
throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "账单不存在");
|
}
|
YwAccount account = ywAccountMapper.selectOne(new QueryWrapper<YwAccount>().lambda()
|
.eq(YwAccount::getCompanyId, bill.getCompanyId())
|
.eq(YwAccount::getIsdeleted, Constants.ZERO)
|
.eq(YwAccount::getStatus, Constants.ZERO)
|
.orderByAsc(YwAccount::getId)
|
.last("limit 1"));
|
if (account == null) {
|
throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "未配置收支账户");
|
}
|
YwContractRevenue revenue = new YwContractRevenue();
|
revenue.setBillId(bill.getId());
|
revenue.setCompanyId(bill.getCompanyId());
|
revenue.setAccountId(account.getId());
|
revenue.setActReceivableFee(order.getAmount());
|
revenue.setActPayDate(new Date());
|
revenue.setPayType(4);
|
revenue.setWxOrderNo(order.getOrderNo());
|
revenue.setRemark("微信H5支付 orderNo=" + order.getOrderNo());
|
revenue.setLoginUserInfo(user);
|
return ywContractRevenueService.create(revenue);
|
}
|
|
private Integer findLatestChargeId(Integer customerId, int type, Integer objId, String orderNo) {
|
YwElectricalCharge charge = ywElectricalChargeMapper.selectOne(new QueryWrapper<YwElectricalCharge>().lambda()
|
.eq(YwElectricalCharge::getCustomerId, customerId)
|
.eq(YwElectricalCharge::getType, type)
|
.eq(type == Constants.ZERO, YwElectricalCharge::getObjId, objId)
|
.eq(YwElectricalCharge::getIsdeleted, Constants.ZERO)
|
.orderByDesc(YwElectricalCharge::getCreateDate)
|
.last("limit 1"));
|
if (charge != null && StringUtils.isBlank(charge.getWxOrderNo())) {
|
ywElectricalChargeMapper.update(null, new UpdateWrapper<YwElectricalCharge>().lambda()
|
.set(YwElectricalCharge::getWxOrderNo, orderNo)
|
.eq(YwElectricalCharge::getId, charge.getId()));
|
return charge.getId();
|
}
|
return charge != null ? charge.getId() : null;
|
}
|
|
private void validateBiz(Integer orderType, Integer bizRefId, Integer customerId, BigDecimal amount) {
|
if (orderType == YwWxPayOrder.TYPE_BILL) {
|
YwContractBill bill = ywContractBillMapper.selectById(bizRefId);
|
if (bill == null || Objects.equals(bill.getIsdeleted(), Constants.ONE)) {
|
throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "账单不存在");
|
}
|
YwContract contract = ywContractMapper.selectById(bill.getContractId());
|
if (contract == null || !Objects.equals(contract.getRenterId(), customerId)) {
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED);
|
}
|
}
|
}
|
|
private Integer resolveBizRefId(CustomerPayCreateDTO dto, Integer customerId) {
|
if (dto.getOrderType() == YwWxPayOrder.TYPE_ELECTRICAL) {
|
if (dto.getElectricalId() == null) {
|
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "电表ID不能为空");
|
}
|
return dto.getElectricalId();
|
}
|
if (dto.getOrderType() == YwWxPayOrder.TYPE_CONDITIONER) {
|
return customerId;
|
}
|
if (dto.getOrderType() == YwWxPayOrder.TYPE_BILL) {
|
if (dto.getBillId() == null) {
|
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "账单ID不能为空");
|
}
|
return dto.getBillId();
|
}
|
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "订单类型无效");
|
}
|
|
private LoginUserInfo buildCustomerUser(Integer customerId) {
|
LoginUserInfo u = new LoginUserInfo();
|
u.setId(customerId);
|
u.setCustomerId(customerId);
|
u.setH5UserType(LoginUserInfo.H5_USER_CUSTOMER);
|
u.setRealname("商户H5");
|
return u;
|
}
|
|
private String successXml() {
|
return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
|
}
|
|
private String failXml(String msg) {
|
return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[" + msg + "]]></return_msg></xml>";
|
}
|
}
|