支付宝&手机网站支付

支付宝接入指引

  1. 通过进入蚂蚁金服商家中心(https://b.alipay.com/?ynsrc=zhuzhanA),进行选择你所要接入的产品,我在这次项目中接入的是手机网站支付。因为以前没有做过支付相关的产品,感觉很高大上,但是实际接入支付宝还是很easy的,只要细心,你可以在几个小时内完成对支付宝的接入,因为我门项目在接入支付宝的同时,还要接入微信,我在接入完这两个产品后,我只能对微信的支付文档说声ZTMS,不废话了,进入正题。
  2. https://auth.alipay.com/login/index.htm?goto=https%3A%2F%2Fenterpriseportal.alipay.com%2Findex.htm     通过这个链接进入支付的登录

  3. 支付宝java版demo

    支付宝代码流程:

    1.调接口,获取支付宝支付需要的参数

    /* 支付宝 */

    $.postJsonToken(payback,{'orderNo': no}, function(data){

    var obj = JSON.parse(data.obj);

    console.log(data)

    var orderNo = obj.orderNo;

    扫描二维码关注公众号,回复: 2413162 查看本文章

    var totalPrice = obj.totalPrice;

    if (data.result == "1") {

              location.href = '../../wappay/pay.jsp?orderNo='+orderNo+'&totalPrice='+totalPrice;

    }else{

              location.href = '../../html/result/fail.html'

    }

    });



    2.通过跳转跳到支付宝demo提供的pay.jsp页面



    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <%@page import="com.axigo.config.AlipayConfig" %>

    <%@page import="com.alipay.api.AlipayClient"%>

    <%@page import="com.alipay.api.DefaultAlipayClient"%>

    <%@page import="com.alipay.api.AlipayApiException"%>

    <%@page import="com.alipay.api.response.AlipayTradeWapPayResponse"%>

    <%@page import="com.alipay.api.request.AlipayTradeWapPayRequest"%>

    <%@page import="com.alipay.api.domain.AlipayTradeWapPayModel" %>

    <%@page import="com.alipay.api.domain.AlipayTradeCreateModel"%>

    <%

    /* *

     * 功能:支付宝手机网站支付接口(alipay.trade.wap.pay)接口调试入口页面

     * 版本:2.0

     * 修改日期:2016-11-01

     * 说明:

     * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。

     请确保项目文件有可写权限,不然打印不了日志。

     */

    %>

    <%

    if(request.getParameter("WIDout_trade_no")!=null){

    // 商户订单号,商户网站订单系统中唯一订单号,必填

        String orderNo = new String(request.getParameter("orderNo").getBytes("UTF-8"),"UTF-8");

        System.out.println("orderNo=========="+orderNo);

    // 商户订单号,商户网站订单系统中唯一订单号,必填

        String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("UTF-8"),"UTF-8");

    // 订单名称,必填

        String subject = new String(request.getParameter("WIDsubject").getBytes("UTF-8"),"UTF-8");

    System.out.println(subject);

        // 付款金额,必填

        String total_amount=new String(request.getParameter("WIDtotal_amount").getBytes("UTF-8"),"UTF-8");

        // 商品描述,可空

        String body = new String(request.getParameter("WIDbody").getBytes("UTF-8"),"UTF-8");

        // 超时时间可空

       String timeout_express="2m";

        // 销售产品码必填

        String product_code="QUICK_WAP_PAY";

        /**********************/

        // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签    

        //调用RSA签名方式

        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);

        AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

       

        // 封装请求支付信息

        AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();

        model.setOutTradeNo(out_trade_no);

        model.setSubject(subject);

        model.setTotalAmount(total_amount);

        model.setBody(body);

        model.setTimeoutExpress(timeout_express);

        model.setProductCode(product_code);

        alipay_request.setBizModel(model);

        // 设置异步通知地址

        alipay_request.setNotifyUrl(AlipayConfig.notify_url);

        // 设置同步地址

        alipay_request.setReturnUrl(AlipayConfig.return_url);  

       

        // form表单生产

        String form = "";

    try {

              // 调用SDK生成表单

              form = client.pageExecute(alipay_request).getBody();

              response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);

        response.getWriter().write(form);//直接将完整的表单html输出到页面

        response.getWriter().flush();

        response.getWriter().close();

    } catch (AlipayApiException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

    }

    }

    %>

    <!DOCTYPE html>

    <html>

    <head>

    <title>支付宝手机网站支付接口</title>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

        <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">

    <style>

        *{

            margin:0;

            padding:0;

        }

        ul,ol{

            list-style:none;

        }

        body{

            font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;

        }

        .hidden{

            display:none;

        }

        .new-btn-login-sp{

            padding: 1px;

            display: inline-block;

            width: 75%;

        }

        .new-btn-login {

            background-color: #02aaf1;

            color: #FFFFFF;

            font-weight: bold;

            border: none;

            width: 100%;

            height: 30px;

            border-radius: 5px;

            font-size: 16px;

        }

        #main{

            width:100%;

            margin:0 auto;

            font-size:14px;

        }

        .red-star{

            color:#f00;

            width:10px;

            display:inline-block;

        }

        .null-star{

            color:#fff;

        }

        .content{

            margin-top:5px;

        }

        .content dt{

            width:100px;

            display:inline-block;

            float: left;

            margin-left: 20px;

            color: #666;

            font-size: 13px;

            margin-top: 8px;

        }

        .content dd{

            margin-left:120px;

            margin-bottom:5px;

        }

        .content dd input {

            width: 85%;

            height: 28px;

            border: 0;

            -webkit-border-radius: 0;

            -webkit-appearance: none;

        }

        #foot{

            margin-top:10px;

            position: absolute;

            bottom: 15px;

            width: 100%;

        }

        .foot-ul{

            width: 100%;

        }

        .foot-ul li {

            width: 100%;

            text-align:center;

            color: #666;

        }

        .note-help {

            color: #999999;

            font-size: 12px;

            line-height: 130%;

            margin-top: 5px;

            width: 100%;

            display: block;

        }

        #btn-dd{

            margin: 20px;

            text-align: center;

        }

        .foot-ul{

            width: 100%;

        }

        .one_line{

            display: block;

            height: 1px;

            border: 0;

            border-top: 1px solid #eeeeee;

            width: 100%;

            margin-left: 20px;

        }

        .am-header {

            display: -webkit-box;

            display: -ms-flexbox;

            display: box;

            width: 100%;

            position: relative;

            padding: 7px 0;

            -webkit-box-sizing: border-box;

            -ms-box-sizing: border-box;

            box-sizing: border-box;

            background: #1D222D;

            height: 50px;

            text-align: center;

            -webkit-box-pack: center;

            -ms-flex-pack: center;

            box-pack: center;

            -webkit-box-align: center;

            -ms-flex-align: center;

            box-align: center;

        }

        .am-header h1 {

            -webkit-box-flex: 1;

            -ms-flex: 1;

            box-flex: 1;

            line-height: 18px;

            text-align: center;

            font-size: 18px;

            font-weight: 300;

            color: #fff;

        }

    </style>

    </head>

    <body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>

    <header class="am-header">

            <h1>支付宝支付</h1>

    </header>

    <div id="main">

            <form name=alipayment action='' method=post target="_blank">

                <div id="body" style="clear:left">

                    <dl class="content">

                        <dt>商户订单号:</dt>

                        <dd>

                            <input id="WIDout_trade_no" name="WIDout_trade_no" />

                        </dd>

                        <hr class="one_line">

                        <dt>订单名称:</dt>

                        <dd>

                            <input id="WIDsubject" name="WIDsubject" />

                        </dd>

                        <hr class="one_line">

                        <dt>付款金额:</dt>

                        <dd>

                            <input id="WIDtotal_amount" name="WIDtotal_amount" />

                        </dd>

                        <hr class="one_line"/>

                        <dt>商品描述:</dt>

                        <dd>

                            <input id="WIDbody" name="WIDbody" />

                        </dd>

                        <hr class="one_line">

                        <dt></dt>

                        <dd id="btn-dd">

                            <span class="new-btn-login-sp">

                                <button class="new-btn-login" type="submit" style="text-align:center;"></button>

                            </span>

                            <span class="note-help">如果您点击“确认”按钮,即表示您同意该次的执行操作。</span>

                        </dd>

                    </dl>

                </div>

              </form>

            <div id="foot">

                       <ul class="foot-ul">

                                <li>

                                        支付宝版权所有 2015-2018 ALIPAY.COM

                                </li>

                       </ul>

              </div>

    </div>

    </body>

    <script language="javascript">

        var package_number = "<%=request.getParameter("orderNo")%>"; 

        var totalPrice = "<%=request.getParameter("totalPrice")%>"; 

        // alert(totalPrice+"=============="+package_number);

    function GetDateNow() {

              var vNow = new Date();

             var sNow = "";

              sNow += String(vNow.getFullYear());

              sNow += String(vNow.getMonth() + 1);

              sNow += String(vNow.getDate());

              sNow += String(vNow.getHours());

              sNow += String(vNow.getMinutes());

              sNow += String(vNow.getSeconds());

              sNow += String(vNow.getMilliseconds());

              document.getElementById("WIDout_trade_no").value =  package_number;

              document.getElementById("WIDsubject").value = "****";

              document.getElementById("WIDtotal_amount").value = totalPrice;

            document.getElementById("WIDbody").value = "****-购物支付";

    }

    GetDateNow();

    </script>

    </html>



    3.异步回调通知页面,不用理会



    <%@page import="net.sf.json.JSONObject"%>

    <%@page import="com.alipay.api.internal.util.AlipaySignature"%>

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    <%@ page import="java.util.*"%>

    <%@ page import="java.util.Map"%>

    <%@ page import="com.axigo.config.*"%>

    <%@ page import="com.alipay.api.*"%>

     

    <%

             //获取支付宝POST过来反馈信息

             Map<String,String> params = new HashMap<String,String>();

             Map requestParams = request.getParameterMap();

             String aa = "";

             for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {

                      String name = (String) iter.next();

                      String[] values = (String[]) requestParams.get(name);

                      String valueStr = "";

                      for (int i = 0; i < values.length; i++) {

                              valueStr = (i == values.length - 1) ? valueStr + values[i]

                                                : valueStr + values[i] + ",";

                      }

                      //乱码解决,这段代码在出现乱码时使用。如果mysignsign不相等也可以使用这段代码转化

                      //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");

                      params.put(name, valueStr);

                      String bb = "";

                      bb = name+"="+valueStr;

    /*            System.out.println("验证成功<br />=============="+name+"========="+valueStr); */

                      aa+="&"+bb;

             }

    /*    System.out.println("=================================="+aa); */

             //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//

                      //商户订单号

     

                      String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

                      //支付宝交易号

     

                      String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

     

                      //交易状态

                      String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

     

                      //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

                      //计算得出通知验证结果

                      //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)

                      boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

    /*            System.out.println("verify_result=============="+verify_result); */

                      if(verify_result){//验证成功

                             

                              //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——

                             

                              if(trade_status.equals("TRADE_FINISHED")){

                                       //判断该笔订单是否在商户网站中已经做过处理

                                                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序

                                                //请务必判断请求时的total_feeseller_id与通知时获取的total_feeseller_id为一致的

                                                //如果有做过处理,不执行商户的业务程序

                                               

                                       //注意:

                                       //如果签约的是可退款协议,退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知

                                       //如果没有签约可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。

                              } else if (trade_status.equals("TRADE_SUCCESS")){

                                       //判断该笔订单是否在商户网站中已经做过处理

                                                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序

                                                //请务必判断请求时的total_feeseller_id与通知时获取的total_feeseller_id为一致的

                                                //如果有做过处理,不执行商户的业务程序

                                               

                                       //注意:

                                       //如果签约的是可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。

                              }

     

                              //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

                              out.clear();

                              out.println("success");    //请不要修改或删除

     

                              //////////////////////////////////////////////////////////////////////////////////////////

                      }else{//验证失败

                              System.out.println("222222222");

                              out.println("fail");

                      }

    %>



    4.同步回调页面,业务逻辑在这个页面进行处理



    <%@page import="net.sf.json.JSONObject"%>

    <%@page import="com.alipay.api.internal.util.AlipaySignature"%>

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    <%@ page import="java.util.*"%>

    <%@ page import="java.util.Map"%>

    <%@ page import="com.axigo.config.*"%>

    <%@ page import="com.alipay.api.*"%>

    <%@ page import="org.apache.commons.httpclient.HttpClient"%>

    <%@ page import="org.apache.commons.httpclient.methods.PostMethod"%>

    <%@ page import="org.apache.commons.lang.StringUtils"%>

    <%@ page import="org.apache.commons.httpclient.Header"%>

    <%@ page import="javax.servlet.http.HttpServletRequest"%>

    <html>

      <head>

                      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

                      <title>支付宝页面跳转同步通知页面</title>

      </head>

      <body>

    <%

             //获取支付宝GET过来反馈信息

             Map<String,String> params = new HashMap<String,String>();

             Map requestParams = request.getParameterMap();

    /*    System.out.println("验证成功<br />11111111111"); */

             for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {

                      String name = (String) iter.next();

                      String[] values = (String[]) requestParams.get(name);

                      String valueStr = "";

                      for (int i = 0; i < values.length; i++) {

                              valueStr = (i == values.length - 1) ? valueStr + values[i]

                                                : valueStr + values[i] + ",";

                      }

                      //乱码解决,这段代码在出现乱码时使用。如果mysignsign不相等也可以使用这段代码转化

                      //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");

                      params.put(name, valueStr);

             /*    System.out.println("验证成功<br />=============="+name+"========="+valueStr); */

             }

            

             //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//

             //商户订单号

     

             String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

             /* System.out.println("out_trade_no=============="+out_trade_no); */

             //支付宝交易号

    /*    String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); */

             String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

             /* System.out.println("trade_no=============="+trade_no); */

             //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

             //计算得出通知验证结果

             //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)

            

            

            

             boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

    /*    System.out.println("verify_result=============="+verify_result); */

             if(verify_result){//验证成功

                      System.out.println("222222222222222222222222222222222222222222222222222222222");

                      //////////////////////////////////////////////////////////////////////////////////////////

                      //请在这里加上商户的业务逻辑程序代码

                      String url=AlipayConfig.CALL_BACK;

                     

                      /* String str = "{\"out_trade_no\":\""+out_trade_no+"\",\"trade_no\":\""+trade_no+"\",\"trade_status\":\""+trade_status+"\"}"; */

                      String str = "{\"out_trade_no\":\""+out_trade_no+"\",\"trade_no\":\""+trade_no+"\",\"payType\":\"ali_pay\"}";

                      System.out.println("str=============="+str);

                      HttpClient client = new HttpClient();

                      PostMethod post = new PostMethod(url);

                      post.addRequestHeader("Content-Type","application/json;charset=utf-8");

                      post.setRequestBody(str);

            

                      client.executeMethod(post);

                      Header[] headers = post.getResponseHeaders();

                      int statusCode = post.getStatusCode();

                      String result = new String(post.getResponseBody());

    /*            System.out.println("result===========================>"+result); */

                      post.releaseConnection();

                      JSONObject jsStr = JSONObject.fromObject(result);

                      System.out.print(jsStr.toString());

            //判断支付成功

            if(String.valueOf(jsStr.get("result")).equals("1")){

                    request.getRequestDispatcher("/html/result/success.html").forward(request,response);

            }else{

                    request.getRequestDispatcher("/html/result/fail.html").forward(request,response);

            }

                      //////////////////////////////////////////////////////////////////////////////////////////

             }else{

                      //该页面可做页面美工编辑

                      out.clear();

                      out.println("验证失败");

             }

    %>

    </body>

    </html>

     


    5、支付成功回调后的业务处理controller



    @Controller

    @RequestMapping("/aliPay/")

    public class AliPayApi {

            

             @Autowired OrderService orderService;

            

             @RequestMapping("pay.htm")

             public @ResponseBody ResultBase pay(@RequestBody Map<String, String> map){

                     

                      return null;

             }

            

             @RequestMapping("callBack.htm")

             public @ResponseBody ResultBase callBack(@RequestBody Map<String, String> map){

                      return orderService.alipayCallBack(map);

             }

     

    }

     

     

    6、进入逻辑处理层进行处理



    @Override

             @Transactional

             public ResultBase wxCallBack(Map<String, String> map) {

                      ResultBase res = new ResultBase();

                      String tradeNo = "";

                      String wxNo = "";

                      String payType = "wx_pay";

                      Date paytime =null;

                      String  total_fee ="";

                     

                      Map<String, Object> param = new HashMap<String, Object>();

                      String where = "";

                      if (CommonUtil.notEmpty(String.valueOf(map.get("out_trade_no")))) {

                              tradeNo = String.valueOf(map.get("out_trade_no"));

                              where += "and order_no =:tradeNo ";

                              param.put("tradeNo", tradeNo);

                      }

                     

                      System.out.println("--------------------------------"+tradeNo);

                     

                      if (CommonUtil.notEmpty(String.valueOf(map.get("time_end")))) {

                              paytime = DateUtil.parse(String.valueOf(map.get("time_end")), "yyyyMMddHHmmss");

                      }

                      System.out.println("--------------------------------"+paytime);

                      if (CommonUtil.notEmpty(String.valueOf(map.get("transaction_id")))) {

                              wxNo = String.valueOf(map.get("transaction_id"));

                      }

                      System.out.println("--------------------------------"+wxNo);

                      if (CommonUtil.notEmpty(String.valueOf(map.get("total_fee")))) {

                              total_fee = String.valueOf(map.get("total_fee"));

                      }

                      System.out.println("--------------------------------"+total_fee);

                     

                      Order order = (Order)orderDAO.setUpQuery(" order_no=? ", null,Long.valueOf(tradeNo)).setMaxResults(1).uniqueResult();

                     

             System.out.println("--------------------------------"+MoneyUtil.changeY2F(String.valueOf(order.getAmount())));

                      //判断金额

    //              if (!total_fee.equals(MoneyUtil.changeY2F(String.valueOf(order.getAmount())))) {

    //                      

    //              }

                      order.setPayTime(paytime);

                      order.setPayType(payType);

                      order.setTradeStatus("SUCCESS");

                      order.setStatus(1);

                      orderDAO.update(order);

                      System.out.println("-------------------订单状态改完-------------");

                      //改库存

                      List<OrderItem> OrderItemList = (List<OrderItem>)orderItemDao.setUpQuery("  order_no = ?", null,Long.valueOf(tradeNo)).list();

                      if(OrderItemList.size()>0){

                              for (OrderItem orderItem : OrderItemList) {

                                       Ptype ptype = orderItem.getPtype();

                                      

                                       System.out.println("-------------------库存ptype.getStock()------------" +ptype.getStock());

                                       System.out.println("-------------------库存orderItem.getQuantity()------------"+orderItem.getQuantity());

                                       ptype.setStock(ptype.getStock()-orderItem.getQuantity());

                                       ptypeDao.update(ptype);

                              }

                      }

                      System.out.println("-------------------库存改完-------------");

                      /**

                       *

                       * 这块改库存!!!!!!!!!!!!!!!!!!!!!!!!!!!

                       */

                      PaymentSerial payment = new PaymentSerial();

                      payment.setOrderNo(String.valueOf(order.getOrderNo()));

                     

                      payment.setTradeNo(wxNo);

                      payment.setAmount(order.getAmount());

                      payment.setStatus(0);

                      payment.setTradeStatus("SUCCESS");

                      payment.setPayType(payType);

                      payment.setPaytime(paytime);

                      payment.setUser(order.getUser());

                      payment.setCreateDate(new Date());

                     

                      if (order.getUser().getIdentity()==0) {

                              if (CommonUtil.notEmpty(order.getUser().getGuide())) {

                                       payment.setGuiuser(order.getUser().getGuide());

                              }

                              if (CommonUtil.notEmpty(order.getUser().getTravelAgency())) {

                                       payment.setTravelAgency(order.getUser().getTravelAgency());

                              }

                             

                      }else{

                              payment.setGuiuser(order.getUser());

                              if (CommonUtil.notEmpty(order.getUser().getTravelAgency())) {

                                       payment.setTravelAgency(order.getUser().getTravelAgency());

                              }

                             

                      }

                     

                      //结算单

                      paymentSerialDao.insert(payment);

                      /*

                      System.out.println(tradeNo);

                      System.out.println(aliNo);

                      System.out.println("已进入!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");*/

                      res.setResult(ResultBase.RESULT_SUCC);

                      return res;

             }

     


    到这里所有的支付流程都走完了,最麻烦的一个点就是验签,主要就是配置公钥和秘钥的配置,其中公钥一定是支付宝公钥而不是应用公钥,切记、切记、切记,如果你理解了相信你也会有慢慢的收获,有什么不明白可以加QQ2409656933.共同探讨


猜你喜欢

转载自blog.csdn.net/guojun13598079464/article/details/80812898