ganxiaomao 5 yıl önce
ebeveyn
işleme
959d0dc8b6

+ 10 - 7
wjj-api/src/main/java/com/demo/wjj/controller/CertificationController.java

@@ -1,5 +1,7 @@
 package com.demo.wjj.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.demo.wjj.po.Agent;
 import com.demo.wjj.po.Sale;
 import com.demo.wjj.po.UserInfo;
@@ -276,6 +278,14 @@ public class CertificationController {
 
             LOG.info("调用四要素验证(/userVerification/getUserVerification)接口成功");
             LOG.debug("调用四要素验证(/userVerification/getUserVerification), apiResult:{}", res);
+
+            //icegan--新增,认证成功则增加销售用户1000积分
+            //JSONObject jo = JSON.parseObject(re)
+            if("".equals("2")){
+                LOG.info("实名认证成功,为销售员,增加1000积分");
+                saleService.addIntegral(openId,1000);
+            }
+
             return res;
         } catch (Exception e) {
             LOG.error("调用四要素验证(/certification/getUserInfo)接口异常", e);
@@ -397,13 +407,6 @@ public class CertificationController {
             LOG.info("调用保存实名认证信息(/certification/saveUserInfo)接口成功");
             LOG.debug("调用保存实名认证信息(/certification/saveUserInfo), apiResult:{}", apiResult);
 
-
-            //icegan--新增,认证成功则增加销售用户1000积分
-            if(status.equals("2")){
-                LOG.info("实名认证成功,为销售员,增加1000积分");
-                saleService.addIntegral(openId,1000);
-            }
-
             return apiResult;
         } catch (Exception e) {
             LOG.error("调用保存实名认证信息(/certification/saveUserInfo)接口异常", e);

+ 222 - 0
wjj-api/src/main/java/com/demo/wjj/controller/PaySaleforController.java

@@ -0,0 +1,222 @@
+package com.demo.wjj.controller;
+
+import com.demo.wjj.bo.CreateOrderBo;
+import com.demo.wjj.bo.CreateOrderResult;
+import com.demo.wjj.po.DiggerAgent;
+import com.demo.wjj.po.Sale;
+import com.demo.wjj.service.*;
+import com.demo.wjj.utils.ApiResult;
+import com.demo.wjj.utils.ExecuteResult;
+import com.demo.wjj.utils.IpUtils;
+import com.demo.wjj.utils.Result;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+@RestController
+@RequestMapping("/paysalefor")
+public class PaySaleforController {
+    private final Logger LOG = LoggerFactory.getLogger(PaySaleforController.class);
+
+    @Autowired
+    private PaySaleforService payforService;
+
+    @Autowired
+    private WeiXinPayService weiXinPayService;
+
+    @Autowired
+    private CreditsExchangeService creditsExchangeService;
+
+    @Autowired
+    private DiggerAgentService diggerAgentService;
+
+    @Autowired
+    private SaleService saleService;//icegan--新增
+
+    /**
+     * 创建微信支付订单
+     *
+     * @param productId 产品id
+     * @param agentId   商家id
+     * @param openId    openId
+     * @param name      联系人姓名
+     * @param mobile    联系人手机
+     * @param tp        是否通票
+     * @return
+     */
+    @PostMapping("/createOrder")
+    public ApiResult createOrder(@RequestParam(required = false) String productId,
+                                 @RequestParam(required = false) String agentId,
+                                 @RequestParam(required = false) String openId,
+                                 @RequestParam(required = false) String name,
+                                 @RequestParam(required = false) String mobile,
+                                 @RequestParam(required = false) String tp,
+                                 HttpServletRequest request) {
+        LOG.info("调用创建保证金微信支付订单(/pay/createOrder)接口, productId:{}, agentId:{}, openId:{}", productId, agentId, openId);
+
+       /* if (StringUtils.isBlank(productId)) {
+            LOG.info("productId为空");
+            return ApiResult.createFailure();
+        }
+*/
+        if (StringUtils.isBlank(agentId)) {
+            LOG.info("agentId为空");
+            return ApiResult.createFailure();
+        }
+
+        if (StringUtils.isBlank(openId)) {
+            LOG.info("openId为空");
+            return ApiResult.createFailure();
+        }
+
+
+        CreateOrderBo createOrderBo = new CreateOrderBo();
+        createOrderBo.setProductId(productId);
+        createOrderBo.setAgentId(agentId);
+        createOrderBo.setOpenId(openId);
+        createOrderBo.setName(name);
+        createOrderBo.setMobile(mobile);
+        /* 手机端用户不能设置通票 wangqing 201811302208
+        createOrderBo.setTp(Integer.parseInt(tp));
+        */
+        createOrderBo.setClientIp(IpUtils.getIp(request));
+        try {
+            ExecuteResult<CreateOrderResult> executeResult = payforService.createOrder(createOrderBo);
+            if (executeResult.isExecuteResult()) {
+                ApiResult<CreateOrderResult> apiResult = ApiResult.createSuccess(executeResult.getData());
+                LOG.info("调用创建保证金微信支付订单(/pay/createOrder)接口成功, apiResult:{}", apiResult);
+
+                //icegan--销售员会员等级修改为金尊会员
+                Sale sale = saleService.getSale(agentId, openId);
+                if(sale != null){
+                    if(sale.getMemberLevel()<2){
+                        LOG.info("更新销售员agentId="+agentId+",openId="+openId+"等级,为金尊会员", apiResult);
+                        saleService.updateMemberLevel(agentId,mobile,2);
+                    }
+                }
+
+                return apiResult;
+            } else {
+                Result result = executeResult.getResult();
+                if (result == null) {
+                    result = Result.Failure;
+                }
+                return new ApiResult(result);
+            }
+
+        } catch (Exception e) {
+            LOG.error("调用创建保证金微信支付订单(/pay/createOrder)接口异常", e);
+            return ApiResult.createFailure();
+        }
+
+    }
+    /**
+     * 微信支付回调
+     * @param request request
+     * @return 响应内容
+     */
+    @RequestMapping(value = "/callback")
+    public String callback(HttpServletRequest request) {
+        LOG.info("调用微信支付订单回调(/pay/callback)接口");
+        ServletInputStream inputStream;
+
+        try {
+            inputStream = request.getInputStream();
+        } catch (IOException e) {
+            LOG.info("调用微信支付订单回调(/pay/callback)接口, 获取请求流异常", e);
+            return "";
+        }
+
+        int b;
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            while ((b = inputStream.read()) != -1) {
+                outputStream.write(b);
+            }
+        } catch (Exception e) {
+            LOG.error("调用微信支付订单回调(/pay/callback)接口, 读取请求流内容异常", e);
+            return "";
+        } finally {
+            try {
+                outputStream.close();
+            } catch (IOException e) {
+                LOG.error("", e);
+            }
+        }
+
+        try {
+            String result = payforService.payCallback(new String(outputStream.toByteArray(), StandardCharsets.UTF_8).trim());
+            LOG.info("调用微信支付订单回调(/pay/callback)接口成功, result => {}", result);
+            return result;
+        } catch (Exception e) {
+            LOG.info("调用微信支付订单回调(/pay/callback)接口异常", e);
+            return "";
+        }
+    }
+
+    @PostMapping("/applyRefund")
+    public ApiResult applyRefund(@RequestParam String id) {
+        LOG.info("调用微信申请退款(/pay/applyRefund)接口, id:{}", id);
+        if (StringUtils.isBlank(id)) {
+            LOG.info("id为空");
+            return ApiResult.createFailure();
+        }
+
+        try {
+            final ExecuteResult<String> executeResult = payforService.refund(id);
+            ApiResult apiResult;
+            if (executeResult.isExecuteResult()) {
+                apiResult = ApiResult.createSuccess(null);
+            } else {
+                apiResult = ApiResult.createFailure();
+                apiResult.setMessage(executeResult.getData());
+            }
+            LOG.info("调用微信申请退款(/pay/applyRefund)接口成功, apiResult:{}", apiResult);
+            return apiResult;
+        } catch (Exception e) {
+            LOG.error("调用微信申请退款(/pay/applyRefund)接口异常", e);
+            return ApiResult.createFailure();
+        }
+    }
+
+    @RequestMapping("/refund/{depositId}/callback")
+    public String refundCallback(@PathVariable String depositId, @RequestBody String xml) {
+        LOG.info("调用微信退款回调(/refund/{appId}/{depositId}/callback)接口, depositId:{}, xml:{}", depositId, xml);
+
+        final String responseXml = "<xml><return_code>${result}</return_code><return_msg></return_msg></xml>";
+
+        if (StringUtils.isBlank(depositId)) {
+            LOG.info("depositId为空");
+            return responseXml.replace("${result}", "FAIL");
+        }
+
+        if (StringUtils.isBlank(xml)) {
+            LOG.info("xml为空");
+            return responseXml.replace("${result}", "FAIL");
+        }
+
+        try {
+            final String result = responseXml.replace("${result}", payforService.refundCallback(depositId, xml));
+            LOG.info("调用微信退款回调(/refund/{appId}/{depositId}/callback)接口成功, result:{}", result);
+            return result;
+        } catch (Exception e) {
+            LOG.info("调用微信退款回调(/refund/{appId}/{depositId}/callback)接口异常", e);
+            return responseXml.replace("${result}", "FAIL");
+        }
+    }
+    @PostMapping("/update")
+    public ApiResult update(@RequestParam String agentId,
+                            @RequestParam String openId){
+        DiggerAgent diggerAgent = diggerAgentService.getDiggerAgent(agentId, openId);
+        boolean result = diggerAgentService.updateIntegral(diggerAgent.getDaId(), 2);
+        return ApiResult.createSuccess(result);
+    }
+}

+ 0 - 9
wjj-api/src/main/java/com/demo/wjj/controller/PayforController.java

@@ -120,15 +120,6 @@ public class PayforController {
                 ApiResult<CreateOrderResult> apiResult = ApiResult.createSuccess(executeResult.getData());
                 LOG.info("调用创建保证金微信支付订单(/pay/createOrder)接口成功, apiResult:{}", apiResult);
 
-                //icegan--销售员会员等级修改为金尊会员
-                Sale sale = saleService.getSale(agentId, openId);
-                if(sale != null){
-                    if(sale.getMemberLevel()<2){
-                        LOG.info("更新销售员agentId="+agentId+",openId="+openId+"等级,为金尊会员", apiResult);
-                        saleService.updateMemberLevel(agentId,mobile,2);
-                    }
-                }
-
                 return apiResult;
             } else {
                 Result result = executeResult.getResult();

+ 16 - 0
wjj-core/src/main/java/com/demo/wjj/mapper/SaleMapper.java

@@ -82,4 +82,20 @@ public interface SaleMapper {
      * @return
      */
     int updateIntegral(@Param("openId") String openId, @Param("memberLevel") Integer integral);
+
+    /**
+     * 根据saleId更新通票状态
+     * @param saleId
+     * @param platTpSet
+     * @return
+     */
+    int updatePlatTpSet(String saleId, Integer platTpSet);
+
+    /**
+     * 根据saleId更新用户等级
+     * @param saleId
+     * @param memberLevel
+     * @return
+     */
+    int updateMemberLevelBySaleId(String saleId, Integer memberLevel);
 }

+ 36 - 0
wjj-core/src/main/java/com/demo/wjj/service/PaySaleforService.java

@@ -0,0 +1,36 @@
+package com.demo.wjj.service;
+
+import com.demo.wjj.bo.CreateOrderBo;
+import com.demo.wjj.bo.CreateOrderResult;
+import com.demo.wjj.utils.ExecuteResult;
+
+/**
+ * icegan--销售员支付固定保证金
+ */
+public interface PaySaleforService {
+    /**
+     *创建订单
+     * @param createOrderBo 创建订单
+     * @return 创建订单结果
+     */
+    ExecuteResult<CreateOrderResult> createOrder(CreateOrderBo createOrderBo);
+    /**
+     * 支付回调
+     * @param xmlStr 回调xml
+     */
+    String payCallback(String xmlStr);
+    /**
+     * 微信退款
+     * @param id 保证金id
+     * @return 退款是否成功
+     */
+    ExecuteResult<String> refund(String id);
+
+    /**
+     * 微信退款回调
+     * @param depositId
+     * @param xml xml
+     * @return
+     */
+    String refundCallback(String depositId, String xml);
+}

+ 16 - 0
wjj-core/src/main/java/com/demo/wjj/service/SaleService.java

@@ -82,4 +82,20 @@ public interface SaleService {
      * @return
      */
     boolean addIntegral(String openId, Integer integral);
+
+    /**
+     * icegan--更新销售员等级
+     * @param saleId
+     * @param memberLevel
+     * @return
+     */
+    boolean updateMemberLevelBySaleId(String saleId, Integer memberLevel);
+
+    /**
+     * 更新销售员通票用户状态
+     * @param saleId
+     * @param platTpSet
+     * @return
+     */
+    boolean updatePlatTpSet(String saleId, Integer platTpSet);
 }

+ 1 - 1
wjj-core/src/main/java/com/demo/wjj/service/impl/PaySaleServiceImpl.java

@@ -235,7 +235,7 @@ public class PaySaleServiceImpl implements PaySaleService {
         newDeposit.setId(UuidUtils.generate());
         newDeposit.setProductName("信誉保证金");
 //        newDeposit.setWxPayNo(prepayId);
-        newDeposit.setDaId(sale.getSaleId());
+        newDeposit.setDaId(sale.getId());
         newDeposit.setAgentId(agentId);
         newDeposit.setAgentName(sale.getSaleName());
         newDeposit.setAgentPayNo(outTradeNo);

+ 817 - 0
wjj-core/src/main/java/com/demo/wjj/service/impl/PaySaleforServiceImpl.java

@@ -0,0 +1,817 @@
+package com.demo.wjj.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.demo.wjj.bo.*;
+import com.demo.wjj.mapper.ExplainMapper;
+import com.demo.wjj.mapper.OfferMapper;
+import com.demo.wjj.po.*;
+import com.demo.wjj.service.*;
+import com.demo.wjj.utils.*;
+import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Service
+public class PaySaleforServiceImpl implements PaySaleforService {
+    private final Logger LOG = LoggerFactory.getLogger(getClass());
+    /**
+     * 回调地址域名
+     */
+    @Value("${weixin.pay.domain}")
+    private String domain;
+    /**
+     * 微信支付接口
+     */
+    @Value("${weixin.pay.apiAddress}")
+    private String payApiAddress;
+    @Value("${jpjgh}")
+    private String jpjgh;
+    @Autowired
+    private DiggerAgentService diggerAgentService;
+    @Autowired
+    private WeiXinPayService weiXinPayService;
+    @Autowired
+    private CreditsExchangeService creditsExchangeService;
+    @Autowired
+    private AgentService agentService;
+    @Autowired
+    private DepositService depositService;
+
+    @Autowired
+    DisplaceAuditService displaceAuditService;
+
+    @Autowired
+    ExplainMapper explainMapper;
+    @Autowired
+    private SaleService saleService;
+    @Autowired
+    OfferMapper offerMapper;
+
+
+
+    @Override
+    @CommitTransactional
+    public ExecuteResult<CreateOrderResult> createOrder(CreateOrderBo createOrderBo) {
+        LOG.info("进入创建订单, createOrderBo:{}", createOrderBo);
+        String agentId = createOrderBo.getAgentId();
+        if (StringUtils.isBlank(agentId)) {
+            LOG.warn("agentId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        String openId = createOrderBo.getOpenId();
+        if (StringUtils.isBlank(openId)) {
+            LOG.warn("微信openId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        String productId = createOrderBo.getProductId();
+    /*    if (StringUtils.isBlank(productId)) {
+            LOG.warn("productId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }*/
+        Agent agent = agentService.getAgent(agentId);
+        if (agent == null) {
+            LOG.info("未查找到商家信息, agentId:{}", agentId);
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        final String appId = agent.getMchAppId();
+        if (StringUtils.isBlank(appId)) {
+            LOG.info("商家appId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        String appSecret = agent.getMchAppSecret();
+        if (StringUtils.isBlank(appSecret)) {
+            LOG.info("商家appSecret为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        String mchId = agent.getMchId();
+        if (StringUtils.isBlank(mchId)) {
+            LOG.info("微信商家mchId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+        Sale sale = saleService.getSale(agentId, openId);
+        if (sale == null) {
+            LOG.info("未查找到销售员信息, agentId:{}, openId:{}", agentId, openId);
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.NO_AUTHORITY);
+        }
+        Integer deposit =  offerMapper.selectDisplaceDeposit(productId);
+
+        CreateOrderParameter orderParameter = new CreateOrderParameter();
+        orderParameter.setAppId(appId);
+        orderParameter.setMchId(mchId);
+        orderParameter.setDeviceInfo("WEB");
+        orderParameter.setNonceStr(generateNonceStr());
+        orderParameter.setBody("固定保证金");
+        orderParameter.setAttach("productId@" + productId);
+        final String outTradeNo = generateTradeNo(agentId, sale.getSaleId());
+        orderParameter.setOutTradeNo(outTradeNo);
+        orderParameter.setTotalFee(deposit);
+        orderParameter.setSpbillCreateIp(createOrderBo.getClientIp());
+        orderParameter.setOpenId(openId);
+        orderParameter.setNotifyUrl(createNotifyUrl());
+        orderParameter.setSign(SignFactory.generate(orderParameter.createRequestParameter(), appSecret));
+
+        // 请求微信接口
+        String parameterXml = orderParameter.toString();
+        LOG.info("请求参数xml格式:{}", parameterXml);
+        byte[] bytes;
+        try {
+            bytes = parameterXml.getBytes("utf-8");
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("编码请求参数异常", e);
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+        HttpResult httpResult = HttpUtils.post(payApiAddress, bytes);
+        if (httpResult.getStatusCode() != 200) {
+            LOG.info("请求微信创建订单接口失败, statusCode:{}", httpResult.getStatusCode());
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+        PaySaleforServiceImpl.OrderResponse response = parseOrderResponse(httpResult.getContent());
+        if (response == null) {
+            LOG.info("解析订单响应内容失败");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+
+        String prepayId = response.getPrepayId();
+        if (StringUtils.isBlank(prepayId)) {
+            LOG.info("解析订单参数prepayId为空");
+            return new ExecuteResult<CreateOrderResult>()
+                    .setExecuteResult(false)
+                    .setResult(Result.Failure);
+        }
+        WeiXinPay weiXinPay = new WeiXinPay();
+        weiXinPay.setProductId(productId);
+        weiXinPay.setProductType(2);
+        weiXinPay.setOrderNo(outTradeNo);
+        weiXinPay.setWxOpenId(openId);
+        weiXinPay.setAgentId(agentId);
+        weiXinPay.setDiggerAgentId(sale.getSaleId());
+        weiXinPay.setDeposit(deposit);
+        weiXinPay.setCreateTime(new Date());
+        weiXinPay.setOrderStatus(WeiXinPay.ORDER_STATUS_WAIT);
+        weiXinPay.setPrepayId(prepayId);
+
+        PayParameterJson payParameter = new PayParameterJson();
+        payParameter.setMobile(createOrderBo.getMobile());
+        payParameter.setName(createOrderBo.getName());
+        /* 手机端用户不能设置通票 wangqing 201811302208
+        payParameter.setTp(createOrderBo.getTp());
+        */
+        weiXinPay.setParameterJson(JSON.toJSONString(payParameter));
+        weiXinPayService.save(weiXinPay);
+        Deposit newDeposit = new Deposit();
+        newDeposit.setId(UuidUtils.generate());
+        newDeposit.setProductName("固定保证金");
+//        newDeposit.setWxPayNo(prepayId);
+        newDeposit.setDaId(sale.getId());
+        newDeposit.setAgentId(agentId);
+        newDeposit.setAgentName(sale.getSaleName());
+        newDeposit.setAgentPayNo(outTradeNo);
+        newDeposit.setPayAmout(new Double(deposit / 100));
+        newDeposit.setPayStatus("0");
+        newDeposit.setPayCreatetime(new Date());
+        /* 手机端用户不能设置通票 wangqing 201811302208
+        newDeposit.setIsCommon(createOrderBo.getTp() + "");
+        */
+        // 默认不是通票, 通票是不需要支付保证金
+        newDeposit.setIsCommon("0");
+        depositService.save(newDeposit);
+        CreateOrderResult createOrderResult = new CreateOrderResult();
+        createOrderResult.setAppId(appId);
+        createOrderResult.setTimeStamp(String.valueOf(System.currentTimeMillis() / 1000));
+        createOrderResult.setNonceStr(RandomUtils.generate(10));
+        createOrderResult.setPackageStr(prepayId);
+        createOrderResult.setSignType("MD5");
+        createOrderResult.setPaySign(SignFactory.generate(createOrderResult.createRequestParameter(), appSecret));
+        createOrderResult.setOrderNo(outTradeNo);
+
+        LOG.info("退出创建订单, createOrderResult:{}", createOrderResult);
+        return new ExecuteResult<CreateOrderResult>().setExecuteResult(true).setData(createOrderResult);
+
+    }
+
+    private PaySaleforServiceImpl.OrderResponse parseOrderResponse(String content) {
+        LOG.info("进入解析订单响应内容, content:{}", content);
+        if (StringUtils.isBlank(content)) {
+            LOG.info("响应内容为空");
+            return null;
+        }
+
+        byte[] bytes = content.getBytes();
+        ByteInputStream byteInputStream = new ByteInputStream(bytes, bytes.length);
+
+        PaySaleforServiceImpl.OrderResponse response = new PaySaleforServiceImpl.OrderResponse();
+        BeanWrapper bean = new BeanWrapperImpl(response);
+        SAXReader reader = new SAXReader();
+        Document document;
+        try {
+            document = reader.read(byteInputStream);
+        } catch (Exception e) {
+            LOG.error("读取响应内容流失败", e);
+            return null;
+        }
+
+        Element root = document.getRootElement();
+        List<Element> elements = root.elements();
+
+        String name;
+        String attribute;
+        for (Element element : elements) {
+            name = element.getName();
+            attribute = response.getAttribute(name);
+
+            if (attribute != null) {
+                bean.setPropertyValue(attribute, element.getStringValue());
+            }
+        }
+        LOG.info("退出解析订单响应内容, response:{}", response);
+        return response;
+    }
+    private String createNotifyUrl() {
+        final String path = "diggerDisplace/payfor/callback";
+
+        if (domain.endsWith("/")) {
+            return domain + path;
+        } else {
+            return domain + "/" + path;
+        }
+    }
+
+    /**
+     * 创建交易订单号
+     * @param agentId 商家id
+     * @param daId 车商id
+     * @return 交易订单号
+     */
+    private String generateTradeNo(String agentId, String daId) {
+        LOG.info("进入创建交易订单号, agentId:{}, daId:{}", agentId, daId);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+        String str = "";
+        final int length = 4;
+        Random random = new Random();
+        for (int i = 1; i <= length; i++) {
+            str += random.nextInt(10);
+        }
+
+        String tradeNo = sdf.format(new Date()) + daId.replace("-", "") + str;
+        LOG.info("退出创建交易订单, tradeNo:{}, daId:{}", tradeNo, daId);
+        return tradeNo;
+    }
+    /**
+     * 生成随机串
+     * @return 随机串
+     */
+    private String generateNonceStr() {
+        final int length = 10;
+        String str = "";
+        Random random = new Random();
+        for (int i = 1; i <= length; i++) {
+            str += random.nextInt(10);
+        }
+        return str;
+    }
+    @Override
+    @CommitTransactional
+    public String payCallback(String xmlStr) {
+        LOG.info("进入微信订单支付回调, xmlStr:{}", xmlStr);
+
+        if (StringUtils.isBlank(xmlStr)) {
+            LOG.info("xmlStr为空");
+            return null;
+        }
+        Map<String, String> result = parseCallBack(xmlStr);
+        if (result == null || MapUtils.isEmpty(result)) {
+            LOG.info("解析微信支付回调xml失败");
+            return null;
+        }
+
+        final String signKey = "sign";
+        String sign = result.get(signKey);
+        if (StringUtils.isBlank(sign)) {
+            LOG.info("sign为空");
+            return null;
+        }
+
+        final String outTradeNoKey = "out_trade_no";
+        String outTradeNo = result.get(outTradeNoKey);
+        if (StringUtils.isBlank(outTradeNo)) {
+            LOG.info("商户订单号为空");
+            return null;
+        }
+
+        final String transactionIdKey = "transaction_id";
+        final String transactionId = result.get(transactionIdKey);
+        if (StringUtils.isBlank(transactionId)) {
+            LOG.info("微信支付订单号为空");
+            return null;
+        }
+
+        WeiXinPay weiXinPay = weiXinPayService.get(outTradeNo);
+        if (weiXinPay == null) {
+            LOG.info("未查找到微信支付订单, outTradeNo:{}", outTradeNo);
+            return null;
+        }
+
+        String response = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
+        if (weiXinPay.getOrderStatus() != 1) {
+            LOG.info("微信订单支付状态为非支付状态, orderStatus:{}", weiXinPay.getOrderStatus());
+            LOG.info("退出微信订单支付回调, result => {}", response);
+            return response;
+        }
+        boolean updateResult = weiXinPayService.updateOrderCallback(outTradeNo, xmlStr);
+        if (!updateResult) {
+            LOG.info("更新微信支付订单回调xml失败");
+            return null;
+        }
+
+        String agentId = weiXinPay.getAgentId();
+        if (StringUtils.isBlank(agentId)) {
+            LOG.info("微信支付订单对应的商家id为空");
+            return null;
+        }
+
+        Agent agent = agentService.getAgent(agentId);
+        if (agent == null) {
+            LOG.info("未查找到商家, agentId:{}", agentId);
+            return null;
+        }
+        String mchAppSecret = agent.getMchAppSecret();
+        if (StringUtils.isBlank(mchAppSecret)) {
+            LOG.info("商家mchAppSecret为空, agentId:{}", agentId);
+            return null;
+        }
+
+        result.remove(signKey);
+        String generateSign = SignFactory.generate(result, mchAppSecret);
+        LOG.info("生成的sign: {}", generateSign);
+        if (!sign.equals(generateSign)) {
+            LOG.info("签名验证失败");
+            return null;
+        }
+        final String returnCodeKey = "return_code";
+        String returnCode = result.get(returnCodeKey);
+        if ("SUCCESS".equals(returnCode)) {
+            final String payMoneyKey = "cash_fee";
+            String payMoney = result.get(payMoneyKey);
+            if (StringUtils.isBlank(payMoney) || !NumberUtils.isDigits(payMoney)) {
+                LOG.info("订单支付金额非法, payMoney:{}", payMoney);
+                return null;
+            }
+
+            if (Integer.parseInt(payMoney) != weiXinPay.getDeposit()) {
+                LOG.info("支付金额与订单金额不一致, payMoney:{}, deposit:{}", payMoney, weiXinPay.getDeposit());
+                weiXinPayService.updateOrderStatus(weiXinPay.getId(), WeiXinPay.ORDER_STATUS_MONEY_ERROR);
+                return null;
+            } else {
+                LOG.info("更新是否支付保证金="+weiXinPay.getProductId());
+                displaceAuditService.updateByDisplaceId(weiXinPay.getProductId(),"2","1");
+                weiXinPayService.updateOrderStatus(weiXinPay.getId(), WeiXinPay.ORDER_STATUS_SUCCESS);
+                depositService.updatePayStatus(weiXinPay.getOrderNo(), transactionId, "1");
+            }
+
+
+
+        } else {
+            boolean updateStatusResult = weiXinPayService.updateOrderStatus(weiXinPay.getId(), WeiXinPay.ORDER_STATUS_FAUILRE);
+            if (!updateStatusResult) {
+                LOG.info("更新订单状态失败");
+                return null;
+            }
+        }
+        saleService.updateMemberLevelBySaleId(weiXinPay.getDiggerAgentId(),2);
+        saleService.updatePlatTpSet(weiXinPay.getDiggerAgentId(),1);//设置为通票
+
+        LOG.info("退出微信订单支付回调, result => {}", response);
+        return response;
+    }
+    /**
+     * 解析回调xml
+     * @param xmlStr xml
+     * @return
+     */
+    private Map<String, String> parseCallBack(String xmlStr) {
+        LOG.info("进入解析微信支付回调xml, xmlStr:{}", xmlStr);
+
+        SAXReader reader = new SAXReader();
+        Document document;
+
+        byte[] bytes;
+        try {
+            bytes = xmlStr.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("编码响应内容异常", e);
+            return null;
+        }
+
+        try {
+            reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+            reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+            reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+
+            document = reader.read(new ByteInputStream(bytes, bytes.length));
+        } catch (Exception e) {
+            LOG.error("读取响应内容异常", e);
+            return null;
+        }
+
+        Map<String, String> result = new HashMap<>();
+        Element root = document.getRootElement();
+        List<Element> elements = root.elements();
+        for (Element element : elements) {
+            result.put(element.getName(), element.getStringValue());
+        }
+        LOG.info("退出解析微信支付回调xml, result => {}", result);
+        return result;
+    }
+
+    private static class OrderResponse {
+        private Map<String, String> attributeMap = new HashMap<>();
+
+        public OrderResponse() {
+            attributeMap.put("return_code", "returnCode");
+            attributeMap.put("return_msg", "returnMsg");
+            attributeMap.put("appid", "appId");
+            attributeMap.put("mch_id", "mchId");
+            attributeMap.put("device_info", "deviceInfo");
+            attributeMap.put("nonce_str", "nonceStr");
+            attributeMap.put("sign", "sign");
+            attributeMap.put("result_code", "resultCode");
+            attributeMap.put("err_code", "errCode");
+            attributeMap.put("err_code_des", "errCodeDes");
+            attributeMap.put("trade_type", "tradeType");
+            attributeMap.put("prepay_id", "prepayId");
+            attributeMap.put("code_url", "codeUrl");
+        }
+
+        @Override
+        public String toString() {
+            return JSON.toJSONString(this);
+        }
+
+        public String getAttribute(String key) {
+            return attributeMap.get(key);
+        }
+
+        private String returnCode;
+        private String returnMsg;
+        private String appId;
+        private String mchId;
+        private String deviceInfo;
+        private String nonceStr;
+        private String sign;
+        private String resultCode;
+        private String errCode;
+        private String errCodeDes;
+        private String tradeType;
+        private String prepayId;
+        private String codeUrl;
+
+        public String getReturnCode() {
+            return returnCode;
+        }
+
+        public void setReturnCode(String returnCode) {
+            this.returnCode = returnCode;
+        }
+
+        public String getReturnMsg() {
+            return returnMsg;
+        }
+
+        public void setReturnMsg(String returnMsg) {
+            this.returnMsg = returnMsg;
+        }
+
+        public String getAppId() {
+            return appId;
+        }
+
+        public void setAppId(String appId) {
+            this.appId = appId;
+        }
+
+        public String getMchId() {
+            return mchId;
+        }
+
+        public void setMchId(String mchId) {
+            this.mchId = mchId;
+        }
+
+        public String getDeviceInfo() {
+            return deviceInfo;
+        }
+
+        public void setDeviceInfo(String deviceInfo) {
+            this.deviceInfo = deviceInfo;
+        }
+
+        public String getNonceStr() {
+            return nonceStr;
+        }
+
+        public void setNonceStr(String nonceStr) {
+            this.nonceStr = nonceStr;
+        }
+
+        public String getSign() {
+            return sign;
+        }
+
+        public void setSign(String sign) {
+            this.sign = sign;
+        }
+
+        public String getResultCode() {
+            return resultCode;
+        }
+
+        public void setResultCode(String resultCode) {
+            this.resultCode = resultCode;
+        }
+
+        public String getErrCode() {
+            return errCode;
+        }
+
+        public void setErrCode(String errCode) {
+            this.errCode = errCode;
+        }
+
+        public String getErrCodeDes() {
+            return errCodeDes;
+        }
+
+        public void setErrCodeDes(String errCodeDes) {
+            this.errCodeDes = errCodeDes;
+        }
+
+        public String getTradeType() {
+            return tradeType;
+        }
+
+        public void setTradeType(String tradeType) {
+            this.tradeType = tradeType;
+        }
+
+        public String getPrepayId() {
+            return prepayId;
+        }
+
+        public void setPrepayId(String prepayId) {
+            this.prepayId = prepayId;
+        }
+
+        public String getCodeUrl() {
+            return codeUrl;
+        }
+
+        public void setCodeUrl(String codeUrl) {
+            this.codeUrl = codeUrl;
+        }
+    }
+
+    @CommitTransactional
+    @Override
+    public ExecuteResult<String> refund(String id) {
+        LOG.info("进入微信退款, id:{}", id);
+
+        if (StringUtils.isBlank(id)) {
+            LOG.info("保证金id为空");
+            return new ExecuteResult<String>().setExecuteResult(false).setData("请求参数错误");
+        }
+
+        Deposit deposit = depositService.getDeposit(id);
+        if (deposit == null) {
+            LOG.info("未查询到保证金, id:{}", id);
+            return new ExecuteResult<String>().setExecuteResult(false).setData("未查询到保证金信息");
+        }
+
+        final String refunded = "2";
+        if (refunded.equals(deposit.getPayStatus())) {
+            LOG.info("保证金已退款, id:{}", id);
+            return new ExecuteResult<String>().setExecuteResult(false).setData("保证金已退款");
+        }
+
+        final String[] allowedRefund = {"1", "4"};  //已支付/退款失败
+        if (!ArrayUtils.contains(allowedRefund, deposit.getPayStatus())) {
+            LOG.info("保证金状态处于不允许退款状态, status:{}", deposit.getPayStatus());
+            return new ExecuteResult<String>().setExecuteResult(false).setData("保证金支付状态错误");
+        }
+
+        final Agent agent = agentService.getAgent(deposit.getAgentId());
+        if (agent == null) {
+            LOG.info("未查找到商家, agentId:{}", deposit.getAgentId());
+            return new ExecuteResult<String>().setExecuteResult(false).setData("未查找到支付保证金对应的商家信息");
+        }
+
+        final String apiUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+
+        final String outRefundNo;
+        if (StringUtils.isBlank(deposit.getRefundNo())) {
+            LOG.info("微信退款单号为空,自动生成单号");
+            outRefundNo = generateTradeNo(agent.getAgentId(), deposit.getDaId());
+        } else {
+            LOG.info("微信退款单号不为空, 使用已存在单号. {}", deposit.getRefundNo());
+            outRefundNo = deposit.getRefundNo();
+        }
+
+        ApplyRefundParameter refundParameter = new ApplyRefundParameter();
+        refundParameter.setAppId(agent.getAppId());
+        refundParameter.setMchId(agent.getMchAppId());
+        refundParameter.setNonceStr(RandomUtils.generate(10));
+        refundParameter.setTransactionId(deposit.getWxPayNo());
+        refundParameter.setOutRefundNo(outRefundNo);
+        final int depositAmount = deposit.getPayAmout().intValue();
+        refundParameter.setTotalFee(depositAmount);
+        refundParameter.setRefundFee(depositAmount);
+        refundParameter.setNotifyUrl(domain + "/pay/refund/" + deposit.getId() + "/callback");
+        refundParameter.setSign(SignFactory.generate(refundParameter.createRequestParameter(), agent.getAppSecret()));
+
+        final String refundFail = "4";
+        String content = null;
+
+        final HttpResult httpResult = HttpUtils.post(apiUrl, refundParameter.toString().getBytes(StandardCharsets.UTF_8));
+        if (httpResult.getStatusCode() != 200) {
+            LOG.info("请求微信退款接口失败, statusCode:{}", httpResult.getStatusCode());
+            updateApplyRefund(deposit.getId(), refunded, content);
+            return new ExecuteResult<String>().setExecuteResult(false).setData("请求微信退款接口失败");
+        }
+
+        content = httpResult.getContent();
+        if (StringUtils.isBlank(content)) {
+            LOG.info("请求微信退款接口, 响应内容为空");
+            updateApplyRefund(deposit.getId(), refundFail, content);
+            return new ExecuteResult<String>().setExecuteResult(false).setData("请求微信退款接口失败");
+        }
+
+        LOG.debug("请求微信退款接口, 响应内容:{}", content);
+
+        ApplyRefundResponse applyRefundResponse = new ApplyRefundResponse();
+        try {
+            applyRefundResponse.parseResponse(content);
+        } catch (DocumentException e) {
+            LOG.error("解析申请微信退款响应内容异常", e);
+            updateApplyRefund(deposit.getId(), refundFail, content);
+            return new ExecuteResult<String>().setExecuteResult(false).setData("请求微信退款接口失败");
+        }
+
+        if ("SUCCESS".equals(applyRefundResponse.getReturnCode())) {
+            if ("SUCCESS".equals(applyRefundResponse.getResultCode())) {
+                LOG.info("请求微信申请退款成功");
+                final String applyRefundSuccess = "3";
+                updateApplyRefund(deposit.getId(), applyRefundSuccess, content);
+                return new ExecuteResult<String>().setExecuteResult(true);
+            } else {
+                LOG.info("请求微信申请退款失败");
+                updateApplyRefund(deposit.getId(), refundFail, content);
+                return new ExecuteResult<String>().setExecuteResult(false).setData(applyRefundResponse.getErrCodeDes());
+            }
+        } else {
+            LOG.info("请求微信申请退款失败");
+            updateApplyRefund(deposit.getId(), refundFail, content);
+            return new ExecuteResult<String>().setExecuteResult(false).setData(applyRefundResponse.getReturnMsg());
+        }
+    }
+
+    @CommitTransactional
+    @Override
+    public String refundCallback(String depositId, String xml) {
+        LOG.info("进入微信退款回调, depositId:{}, xml:{}", depositId, xml);
+
+        final Deposit deposit = depositService.getDeposit(depositId);
+        if (deposit == null) {
+            LOG.info("未查找到保证金, depositId:{}", depositId);
+            return "FAIL";
+        }
+
+        if ("2".equals(deposit.getPayStatus())) {
+            LOG.info("保证金已退款, depositId:{}", deposit);
+            return "SUCCESS";
+        }
+
+        if (!"3".equals(deposit.getPayStatus())) {
+            LOG.info("保证金状态未非退款中状态, status:{}", deposit.getPayStatus());
+            return "FAIL";
+        }
+
+        final Agent agent = agentService.getAgent(deposit.getAgentId());
+        if (agent == null) {
+            LOG.info("未查找到商家, agentId:{}", deposit.getAgentId());
+            return "FAIL";
+        }
+
+        final String refundFail = "4";
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
+        SAXReader reader = new SAXReader();
+        try {
+            final Document document = reader.read(inputStream);
+            final Element rootElement = document.getRootElement();
+            final String returnCode = rootElement.element("return_code").getStringValue();
+
+            if ("SUCCESS".equals(returnCode)) {
+                final Element reqInfo = rootElement.element("req_info");
+                if (reqInfo == null) {
+                    LOG.info("xml中未包含req_info节点");
+                    updateRefund(depositId, refundFail, xml);
+                    return "FAIL";
+                }
+                final String reqInfoContent = reqInfo.getStringValue();
+                final byte[] decodeBase64 = Base64.decodeBase64(reqInfoContent.getBytes(StandardCharsets.UTF_8));
+                final String secretMD5 = DigestUtils.md5Hex(agent.getMchAppSecret()).toLowerCase();
+                final String name = "AES/ECB/PKCS7Padding";
+                String decryptXml;
+                try {
+                    Cipher cipher = Cipher.getInstance(name, "BC");
+                    SecretKeySpec keySpec = new SecretKeySpec(secretMD5.getBytes(StandardCharsets.UTF_8), "AES");
+                    cipher.init(Cipher.DECRYPT_MODE, keySpec);
+                    byte[] decoded = cipher.doFinal(decodeBase64);
+                    decryptXml = new String(decoded, StandardCharsets.UTF_8);
+                    LOG.info("微信退款解密xml:{}", decryptXml);
+                } catch (Exception e) {
+                    LOG.error("解密微信退款xml异常", e);
+                    updateRefund(depositId, refundFail, xml);
+                    return "FAIL";
+                }
+
+                ByteArrayInputStream inputStream1 = new ByteArrayInputStream(decryptXml.getBytes(StandardCharsets.UTF_8));
+                SAXReader reader1 = new SAXReader();
+                final Document document1 = reader1.read(inputStream1);
+                final Element rootElement1 = document1.getRootElement();
+                final String refundStatus = rootElement1.element("refund_status").getStringValue();
+                final String refundSuccess = "2";
+                updateRefund(depositId, "SUCCESS".equalsIgnoreCase(refundStatus) ? refundSuccess : refundFail, xml);
+                LOG.info("退出微信退款回调");
+                return "SUCCESS";
+
+            } else {
+                LOG.info("微信退款失败");
+                updateRefund(depositId, refundFail, xml);
+                return "FAIL";
+            }
+
+        } catch (Exception e) {
+            LOG.error("解析微信退款回调xml异常", e);
+            updateRefund(depositId, refundFail, xml);
+            return "FAIL";
+        }
+    }
+
+    private void updateApplyRefund(String id, String status, String xml) {
+        depositService.updateApplyRefund(id, status, xml);
+    }
+
+    private void updateRefund(String id, String status, String xml) {
+        depositService.updateRefund(id, status, xml);
+    }
+}

+ 12 - 0
wjj-core/src/main/java/com/demo/wjj/service/impl/SaleServiceImpl.java

@@ -147,5 +147,17 @@ public class SaleServiceImpl implements SaleService {
         return saleMapper.updateIntegral(openId,integral)>0;
     }
 
+    @Override
+    public boolean updateMemberLevelBySaleId(String saleId, Integer memberLevel) {
+        LOG.info("进入更新销售员会员等级, saleId:{}, memberLevel:{}", saleId,memberLevel);
+        return saleMapper.updateMemberLevelBySaleId(saleId, memberLevel)>0;
+    }
+
+    @Override
+    public boolean updatePlatTpSet(String saleId, Integer platTpSet) {
+        LOG.info("进入更新销售员会员通票, saleId:{}, memberLevel:{}", saleId,platTpSet);
+        return saleMapper.updatePlatTpSet(saleId, platTpSet)>0;
+    }
+
 
 }

+ 10 - 0
wjj-core/src/main/resources/mybatis/SaleMapper.xml

@@ -71,6 +71,16 @@
         where wx_openid = #{openId}
     </update>
 
+    <update id="updateMemberLevelBySaleId">
+        update tb_sales set member_level = #{memberLevel}
+        where sale_id = #{saleId}
+    </update>
+
+    <update id="updatePlatTpSet">
+        update tb_sales set plat_tp_set = #{platTpSet}
+        where sale_id = #{saleId}
+    </update>
+
     <delete id="deleteBy">
         delete from tb_sales
         where user_id = #{userId}