java进行支付宝支付(沙箱环境)

news2024/11/28 4:53:10

目录

1.准备工作

2.idea配置文件准备

3.后端代码编写

接口1:支付订单

接口2:查询订单

接口3:订单退款

接口4:查询退款结果

接口5:获取总账单

接口6:取消订单

接口7:回调接口

定时任务:主动查询订单

4.前端代码编写

5.验证 

支付订单

查询订单

订单退款

查询退款

取消订单


1.准备工作

进入沙箱控制台获取自己的买家卖家id、网关等配置信息
快速接入 - 支付宝文档中心 (alipay.com)

将沙箱工具下载本地,方便支付和调试,支付宝沙箱版

2.idea配置文件准备


properties设置自己沙箱的信息:8个值

#alipay 沙箱环境
#自己的appid  沙箱应用里面
alipay.app-id=xxx
#商户pid 沙箱账号里面
alipay.seller-id=xxx
#支付宝公钥 沙箱应用里面  公钥模式-》查看
alipay.alipay-public-key=xxx
#应用私钥 沙箱应用里面
alipay.merchant-private-key=xxx
#支付宝网关地址 沙箱应用里面
alipay.gateway-url= xxx
#接口内容加密方式 沙箱应用里面-》接口内容加密方式
alipay.content-key=xxx
#支付回调返回地址 如果自己有页面就写,没的话就返回百度
alipay.return-url = https://www.baidu.com
#支付回调公网地址+接口   这个需要通过ngrok穿透,让自己本地的项目映射到公网 这里不多讲解
alipay.notify-url = xxx

3.后端代码编写

controller层:接口总共7个接口,其中有一个是支付宝回调接口,就是你支付完成后,支付宝调用你提供的接口给你传回调消息,所以需要你这个接口是能够在公网访问的接口,因此对于本地环境来说需要内网穿透。

接口1:支付订单

根据前端选择的商品id/编号,传入后台后,调用AlipayTradePagePayModel进行参数设置,最后通过AlipayTradePagePayRequest,设置1支付成功后的回调地址我写的百度2回调在哪个接口暴漏公网的接口,然后执行pageExecute完成签名执行请求

实现代码如下:

impl层代码

 public String createPay(Long orderId) {
        //1.请求
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //2.设置数据
        AlipayTradePagePayModel bizModel = new AlipayTradePagePayModel();
        // 商品编号
        bizModel.setOutTradeNo(orderId.toString());
        //单位是元
        bizModel.setTotalAmount(String.valueOf(0.01));
        // 订单标题
        bizModel.setSubject("测试商品");
        //默认的
        bizModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        //3.绑定
        request.setBizModel(bizModel);
        // 支付成功后返回哪里
        request.setReturnUrl(returnUrl);
        // 结果回调地址
        request.setNotifyUrl(notifyUrl);
        //用户支付后支付宝会以GET方法请求returnUrl,并且携带out_trade_no,trade_no,total_amount等参数.
        AlipayTradePagePayResponse response = null;
        try {
            //完成签名并执行请求
            response = alipayClient.pageExecute(request);
            if (response.isSuccess()) {
                log.debug("调用成功,参数为===>{}",JSON.toJSONString(response.getBody()));
                return response.getBody();
            } else {
                log.error("调用失败");
                log.error(response.getMsg());
                return null;
            }
        } catch (AlipayApiException e) {
            log.error("调用异常");
            return null;
        }
    }

支付回调接口

  /**
     * 支付宝回调
     * 发起支付后,商户进行的验证和保存记录等操作
     * 这个接口地址是根据配置文件进行配置的
     * @param params 支付宝返回的
     * @return 返回给支付宝的  只有两种状态 success  failure
     */
    @PostMapping("/tradeNotify")
    public String tradeNotify(@RequestParam Map<String, String> params) {
//        支付通知正在执行
//        通知参数===>
//        {
//        "gmt_create":"2023-11-01 09:59:50",
//        "charset":"UTF-8",
//        "gmt_payment":"2023-11-01 10:00:15",
//        "notify_time":"2023-11-01 10:00:17",
//        "subject":"测试商品",
//        "sign":"f5/aoi4fNs+DZRuyqFr6uU1J6l6sImbZLZzJvYl76tDJFRW+gv3Ewk2DW6EemdD9zNt0QNpagfp3IS0CVDKnTrVly4aA/QehNQ9f6Ru9kNU9lqRhc/GRx2ikuQgYw7MUeoMLXNSL5xh9G09bVFBwl7iYa/I2fh8FgFQTyDgjUVjsFen7Kokt70DNi1KIWyuD7qLCMu7SRYP0NtNp6kA1AoRhx6zpu2MOCqRVlsMeQyYB5fbj0sWJcWogWBYcUuzTZrLE0X/lc7a8hMYw63IhBag47L9sbtxcZfOIq1Sd7/L20fmaPLl0PZllbILad+O6uIRXBRC5PvZa/t9IN2A2gw==",
//        "buyer_id":"2088722019936375",
//        "invoice_amount":"0.01",
//        "version":"1.0",
//        "notify_id":"2023110101222100016036370501117115",
//        "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
//        "notify_type":"trade_status_sync",
//        "out_trade_no":"486789",
//        "total_amount":"0.01","
//        trade_status":"TRADE_SUCCESS",
//        "trade_no":"2023110122001436370501040720",
//        "auth_app_id":"9021000131620971",
//        "receipt_amount":"0.01",
//        "point_amount":"0.00",
//        "buyer_pay_amount":"0.01",
//        "app_id":"9021000131620971",
//        "sign_type":"RSA2",
//        "seller_id":"2088721019958624"
//        }
        log.info("支付回调正在执行");
        log.info("支付宝回调参数为===>{}", JSON.toJSONString(params));
        //验签
        boolean signVerified = false;
        String result = "failure";
        try {
            // 入参
            signVerified = AlipaySignature.rsaCheckV1(params, aliPayPublicKey, AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
            //验签成功
            if (signVerified) {
                log.info("验签成功");
                // 1.商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号  数据库查询这条记录是否存在?在生成订单的时候创建订单
                String out_trade_no = params.get("out_trade_no");
                // 根据订单号查询这条记录,返回order,如果不存在返回result(failure)

                // 2.商户需要验证该通知数据中的total_amount是否为该订单的实际金额(即商户订单创建时的金额)
                String totalAmount = params.get("total_amount");
                int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue();
                // 将order中的价格拿出来跟这个作比较,若不同返回result(failure)

                // 3. 校验通知中的seller_id(或者sell_email)是否为out_trade_no 这笔单据的对应的操作方法  需要保持与商户pid一致
                String sellerId = params.get("seller_id");
                if (!sellerId.equals(aliPaySellerId)){
                    log.error("商家pid校验失败");
                    return result;
                }

                // 4. 验证app_id 是否为商户本身
                String appId = params.get("app_id");
                if (!appId.equals(aliPayAppId)){
                    log.error("appId校验失败");
                    return result;
                }

                // 5. 验证交易通知是否为TRADE_SUCCESS,只有为TRADE_SUCCESS支付宝才会认定买家付款成功
                String tradeStatus = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(tradeStatus)){
                    log.error("支付未成功");
                    return result;
                }

                // 处理订单后续
                log.info("5大校验验证通过,开始对回调函数进行处理");
                aliPayService.processOrder(params);
                result = "success";
                return result;
            } else {
                log.error("验签失败");
                return result;
            }
        } catch (AlipayApiException e) {
            log.error("验签异常");
            return result;
        }
    }

impl

 @Override
    public void processOrder(Map<String, String> params) {
        String out_trade_no = params.get("out_trade_no");
        //支付宝支付中的支付编号
        String trade_no = params.get("trade_no");
        //交易类型(扫码 登录等等)
        String trade_status = params.get("trade_status");
        //存放全部数据(json)以备不时之需
        String s = JSON.toJSONString(params);

        // 将订单状态查询出来,如果是未支付就继续执行下面操作  仅仅只有未支付才进行下面操作
        // 如果已经支付就return
        if (lock.tryLock()) {
            try {
                log.info("幂等性校验开始");
//                if (!"未支付".equals("调用数据库查询")) {
//                    return;
//                }
                // 更新订单状态

                // 记录支付日志
                log.info("幂等性校验结束");
                log.info("订单{}的支付日志已添加,状态已更改为已支付,支付宝记录编号为{}", out_trade_no, trade_no); //订单789454的支付记录添加成功,支付记录id为2023110122001436370501040721.
            } catch (Exception e) {

            } finally {
                lock.unlock();
            }
        }
    }

接口2:查询订单

前端传入商品id/编号,后端封装数据使用AlipayTradeQueryModel,用AlipayTradeQueryRequest发起请求。

实现代码如下:

 @Override
    public String queryPay(String orderNo) {
        //请求
        AlipayTradeQueryRequest request=new AlipayTradeQueryRequest();
        //数据
        AlipayTradeQueryModel bizModel=new AlipayTradeQueryModel();
        bizModel.setOutTradeNo(orderNo);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayTradeQueryResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("查询订单{}成功",orderNo);
                return response.getBody();
            }
            else{
                log.error("查询订单{}失败,响应数据是{}.",orderNo,response.getBody());
                return null;
            }
        }
        catch(AlipayApiException e){
            log.error("查询订单{}异常",orderNo);
            return null;
        }
    }

接口3:订单退款

传入两个参数,商品id/编号和退款原因

需要注意点是如果封装数据时传入了退款订单号(自己设置的),那么在后面查询订单退款信息时也需要传入这个退款订单号,如果这里没有设置,后面的退款订单号就是商品id/编号

实现代码如下:

 @Override
    public void refund(String orderNo, String reason) {
        //请求
        AlipayTradeRefundRequest request=new AlipayTradeRefundRequest();
        //数据
        AlipayTradeRefundModel bizModel=new AlipayTradeRefundModel();
        //订单号
        bizModel.setOutTradeNo(orderNo);
        // 退款金额
        bizModel.setRefundAmount("0.01");
        //退款原因
        bizModel.setRefundReason(reason);
        request.setBizModel(bizModel);
        log.info("签名入参===>{}",JSON.toJSONString(request));
        try{
            //完成签名并执行请求
            AlipayTradeRefundResponse response=alipayClient.execute(request);
            //成功则说明退款成功了
            if(response.isSuccess()){
                log.info("订单{}退款成功",orderNo);
            }
            else{
                log.error("订单{}退款失败,错误原因===>{}",orderNo,response.getSubMsg());
                throw new RuntimeException("订单退款失败");
            }
        }
        catch(AlipayApiException e){
            log.error("订单{}退款异常",orderNo);
            throw new RuntimeException("订单退款异常");
        }
    }

接口4:查询退款结果

前端传入订单编号,后端进行查询,注意点就是刚才所说退款订单号问题,如果退款时没传退款订单号,这里就传订单号

实现代码如下:

 @Override
    public String queryRefund(String orderNo) {
        AlipayTradeFastpayRefundQueryRequest request=new AlipayTradeFastpayRefundQueryRequest();
        AlipayTradeFastpayRefundQueryModel bizModel=new AlipayTradeFastpayRefundQueryModel();
        //订单号
        bizModel.setOutTradeNo(orderNo);
        // 退款订单号,如果退款时候没有传退款订单号,那么查询时就传订单号
        bizModel.setOutRequestNo(orderNo);
        //想要额外返回的数据(也就是文档中响应可选的数据)
        ArrayList<String> extraResponseDatas=new ArrayList<>();
        extraResponseDatas.add("refund_status");
        bizModel.setQueryOptions(extraResponseDatas);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayTradeFastpayRefundQueryResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("退款{}查询成功",orderNo);
                return JSON.toJSONString(response.getBody());
            }
            else{
                log.debug("退款{}查询失败,原因是==>{}",orderNo,response.getSubMsg());
                return null;
            }
        }
        catch(AlipayApiException e){
            log.debug("退款{}查询异常",orderNo);
            return null;
        }
    }

接口5:获取总账单

根据账单类型和日期获取账单url地址,这里出参是url,放在浏览器直接下载

实现代码如下:

 @Override
    public String queryBill(String billDate, String type) {
        //请求
        AlipayDataDataserviceBillDownloadurlQueryRequest request=new AlipayDataDataserviceBillDownloadurlQueryRequest();
        //数据
        AlipayDataDataserviceBillDownloadurlQueryModel bizModel=new AlipayDataDataserviceBillDownloadurlQueryModel();
        bizModel.setBillType(type);
        bizModel.setBillDate(billDate);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayDataDataserviceBillDownloadurlQueryResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("获取账单下载url成功");
                return response.getBillDownloadUrl();
            }
            else{
                log.error("获取账单下载url失败,原因是===>{}",response.getSubMsg());
                return null;
            }
        }
        catch(AlipayApiException e){
            log.error("获取账单下载url异常");
            return null;
        }
    }

接口6:取消订单

传入商品id/编号,后端封装数据,完成签名后进行取消

实现代码如下:

 private void closePay(String orderNo) {

        log.info("关单接口的订单号,订单号===>{}",JSON.toJSONString(orderNo));
        //请求
        AlipayTradeCloseRequest request=new AlipayTradeCloseRequest();
        //数据
        AlipayTradeCloseModel bizModel=new AlipayTradeCloseModel();
        bizModel.setOutTradeNo(orderNo);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayTradeCloseResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("订单{}取消成功",orderNo);
            }
            else{
                log.info("订单{}取消失败,原因==>{}",orderNo,response.getSubMsg());
                throw new RuntimeException("关单接口调用失败");
            }
        }
        catch(AlipayApiException e){
            log.error("订单{}取消异常",orderNo);
            throw new RuntimeException("关单接口异常");
        }
    }

接口7:回调接口

当发起支付后,支付宝会调该接口进行数据返回,需要验证签名和5个参数

  @PostMapping("/tradeNotify")
    public String tradeNotify(@RequestParam Map<String, String> params) {
//        支付通知正在执行
//        通知参数===>
//        {
//        "gmt_create":"2023-11-01 09:59:50",
//        "charset":"UTF-8",
//        "gmt_payment":"2023-11-01 10:00:15",
//        "notify_time":"2023-11-01 10:00:17",
//        "subject":"测试商品",
//        "sign":"f5/aoi4fNs+DZRuyqFr6uU1J6l6sImbZLZzJvYl76tDJFRW+gv3Ewk2DW6EemdD9zNt0QNpagfp3IS0CVDKnTrVly4aA/QehNQ9f6Ru9kNU9lqRhc/GRx2ikuQgYw7MUeoMLXNSL5xh9G09bVFBwl7iYa/I2fh8FgFQTyDgjUVjsFen7Kokt70DNi1KIWyuD7qLCMu7SRYP0NtNp6kA1AoRhx6zpu2MOCqRVlsMeQyYB5fbj0sWJcWogWBYcUuzTZrLE0X/lc7a8hMYw63IhBag47L9sbtxcZfOIq1Sd7/L20fmaPLl0PZllbILad+O6uIRXBRC5PvZa/t9IN2A2gw==",
//        "buyer_id":"2088722019936375",
//        "invoice_amount":"0.01",
//        "version":"1.0",
//        "notify_id":"2023110101222100016036370501117115",
//        "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
//        "notify_type":"trade_status_sync",
//        "out_trade_no":"486789",
//        "total_amount":"0.01","
//        trade_status":"TRADE_SUCCESS",
//        "trade_no":"2023110122001436370501040720",
//        "auth_app_id":"9021000131620971",
//        "receipt_amount":"0.01",
//        "point_amount":"0.00",
//        "buyer_pay_amount":"0.01",
//        "app_id":"9021000131620971",
//        "sign_type":"RSA2",
//        "seller_id":"2088721019958624"
//        }
        log.info("支付回调正在执行");
        log.info("支付宝回调参数为===>{}", JSON.toJSONString(params));
        //验签
        boolean signVerified = false;
        String result = "failure";
        try {
            // 入参
            signVerified = AlipaySignature.rsaCheckV1(params, aliPayPublicKey, AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
            //验签成功
            if (signVerified) {
                log.info("验签成功");
                // 1.商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号  数据库查询这条记录是否存在?在生成订单的时候创建订单
                String out_trade_no = params.get("out_trade_no");
                // 根据订单号查询这条记录,返回order,如果不存在返回result(failure)

                // 2.商户需要验证该通知数据中的total_amount是否为该订单的实际金额(即商户订单创建时的金额)
                String totalAmount = params.get("total_amount");
                int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue();
                // 将order中的价格拿出来跟这个作比较,若不同返回result(failure)

                // 3. 校验通知中的seller_id(或者sell_email)是否为out_trade_no 这笔单据的对应的操作方法  需要保持与商户pid一致
                String sellerId = params.get("seller_id");
                if (!sellerId.equals(aliPaySellerId)){
                    log.error("商家pid校验失败");
                    return result;
                }

                // 4. 验证app_id 是否为商户本身
                String appId = params.get("app_id");
                if (!appId.equals(aliPayAppId)){
                    log.error("appId校验失败");
                    return result;
                }

                // 5. 验证交易通知是否为TRADE_SUCCESS,只有为TRADE_SUCCESS支付宝才会认定买家付款成功
                String tradeStatus = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(tradeStatus)){
                    log.error("支付未成功");
                    return result;
                }

                // 处理订单后续
                log.info("5大校验验证通过,开始对回调函数进行处理");
                // 进行自己的业务操作
                aliPayService.processOrder(params);
                result = "success";
                return result;
            } else {
                log.error("验签失败");
                return result;
            }
        } catch (AlipayApiException e) {
            log.error("验签异常");
            return result;
        }
    }

定时任务:主动查询订单

除了回调这个被动查询外,我们也可以通过定时任务来进行定时查询表中未支付的订单和支付宝中的状态,来保证一致性。

定时把表中未支付的订单拿出来,进行查询

 /**
     * 从第0秒开始每隔30s执行一次,查询创建超过5分钟且未支付的订单
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void orderConfirm(){
        log.info("orderConfirm被执行...");
        // 1.查询本地未支付的记录,这里写死了
        String orderNo = "9956851223";
        // 2.核实订单状态,调用支付宝查单接口
        aliPayService.checkPayStatus(orderNo);
    }
  /**
     * 查询支付宝订单状态
     * @param orderNo
     */
    @Override
    public void checkPayStatus(String orderNo) {
        log.info("根据订单号核实订单状态=====>{}",JSON.toJSONString(orderNo));
        // 查询支付宝这个订单的状态
        String result = this.queryPay(orderNo);
        // 1.如果未创建
        if (result == null){
            log.info("订单未创建===>{}",JSON.toJSONString(orderNo));
            // 更新订单状态
            return;
        }
        System.out.println("result"+result);
        // 获取订单状态
        String alipayTradeQueryResponse1 = JSON.parseObject(result).get("alipay_trade_query_response").toString();
        String tradeStatus = JSON.parseObject(alipayTradeQueryResponse1).get("trade_status").toString();

        // 2.订单状态如果是未支付
        if (AliPayTradeState.NOTYPE.getType().equals(tradeStatus)){
            log.info("订单未支付===>{}",JSON.toJSONString(orderNo));
            // 调用关单接口
            this.closePay(orderNo);
            // 更新订单状态
        }
        // 3.订单状态如果是已支付
       if (AliPayTradeState.SUCCESS.getType().equals(tradeStatus)){
            log.info("订单已支付===>{}",JSON.toJSONString(orderNo));
            // 更新商户订单状态
            // 记录支付日志
        }
        // 4. 订单状态如果是已关闭
        if (AliPayTradeState.CLOSED.getType().equals(tradeStatus)){
            log.info("订单已关闭===>{}",JSON.toJSONString(orderNo));
            // 更新商户订单状态
            // 记录支付日志
        }
    }
public enum AliPayTradeState {
    /**
     * 支付成功
     */
    SUCCESS("TRADE_SUCCESS"),
    /**
     * 未支付
     */
    NOTYPE("WAIT_BUYER_PAY"),
    /**
     * 已关闭
     */
    CLOSED("TRADE_CLOSED");

    private String type;

}

4.前端代码编写

<!doctype html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Login</title>
        <script src="js/jquery-1.8.3.min.js"></script>
    </head>

    <script>
        function zhifu(){
            $.ajax({	
                url:"http://localhost:8080/pay/createPay/995685122334",
                type:"post",
                success: function(data) {
                    // console.log(data)
                    document.write(data.body)
                }
            })
        }
    
    </script>
<script>
    function guanbi(){
        $.ajax({	
            url:"http://localhost:8080/pay/cancelPay/995685122334",
            type:"post",
            success: function(data) {
                alert(data.msg)
            }
        })
    }
</script>

<script>
    function tuikuan(){
        $.ajax({	
            url:"http://localhost:8080/pay/refunds/995685122334/不想要了",
            type:"post",
            success: function(data) {
                alert(data.msg)
            }
        })
    }
</script>

<script>
    function chaxuntuikuan(){
        $.ajax({	
            url:"http://localhost:8080/pay/queryRefund/995685122334",
            type:"post",
            success: function(data) {
                console.log(data)
            }
        })
    }
</script>

<script>
    function chaxun(){
        $.ajax({	
            url:"http://localhost:8080/pay/query/995685122334",
            type:"get",
            success: function(data) {
               console.log(data)
            }
        })
    }
</script>


<script>
    function duizhangliushui(){
        $.ajax({	
            url:"http://localhost:8080/pay/downloadurl/query/2023-10-31/trade",
            type:"get",
            success: function(data) {
                console.log(data.body)
            //    alert(data.body)
            }
        })
    }
</script>
  <body>
    <div style="margin: 0 auto; width: 600px; height: 600px; text-align: center; margin-top: 300px; display: flex;">
<div style="width:50px; height:50px;left: auto;">
    <button onclick="zhifu()">支付</button>
</div>
    <div style="width:100px; height:50px;left: auto;">
    <button onclick="chaxun()">查询订单</button>
</div>
    <div style="width:50px; height: 50px;left: auto;">
    <button onclick="tuikuan()">退款</button>
</div>
    <div style="width:100px; height: 50px;left: auto;">
    <button onclick="guanbi()">取消订单</button>
</div>
<div style="width:100px; height: 50px;left: auto;">
    <button onclick="chaxuntuikuan()">查询退款</button>
</div>

<div style="width:100px; height: 50px;left: auto;">
    <button onclick="duizhangliushui()">对账流水</button>
</div>
    </div>
    
  </body>

</html>

5.验证 

支付订单

点击支付按钮

手机沙箱版支付宝扫码支付。

然后前端页面就跳转到百度了,因为设置回调跳转到百度

查询订单

订单退款

查询退款

取消订单

重新下一单,但是扫码后不付款

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1160329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【stata基础代码大全 】 可独立完成一篇实证

【stata基础代码大全 】 可独立完成一篇实证 用stata打开&#xff0c;直接替换自己需要的变量就行&#xff0c;小白友好❗️❗️❗️ 文件包括以下内容 一、数据预处理 二、Stata中数据的基本处理 *(1)取年份 *(2)剔除数据中的样本 *(3)生成新的变量 *(4)给变量添加标签 *(5)生…

开关电源测试过压保护的测试标准及其方法

过压保护的原理 过压保护是电压超过预定值时降低电压的一种方式&#xff0c;原理是通过电路中的电压检测电路来检测电路中的电压是否超过了设定的阈值&#xff0c;如果超过了阈值&#xff0c;就会触发过压保护器件&#xff0c;使电源断开或使受控设备电压降低&#xff0c;保护电…

智慧矿山:AI算法在带式运输机中的异物识别应用

随着现代农业和工业的发展&#xff0c;带式运输机在各种生产作业中发挥着越来越重要的作用。然而&#xff0c;在带式运输机运行过程中&#xff0c;可能会混入各种异物&#xff0c;这些异物的存在可能会对运输过程和设备本身造成损害。为了解决这一问题&#xff0c;本文将介绍一…

VVG PAD DM蓝牙5.2双模热插拔PCB

键盘使用说明索引&#xff08;均为出厂默认值&#xff09; 软件支持&#xff08;驱动的详细使用帮助&#xff09;一些常见问题解答&#xff08;FAQ&#xff09;请认真阅读本说明首次使用步骤蓝牙配对规则&#xff08;重要&#xff09;蓝牙和USB切换键盘默认层默认触发层0的FN键…

低代码,程序员提高生产力的开发工具

目录 一、什么是低代码&#xff1f; 二、低代码的本质是什么&#xff1f; 三、低代码平台的搭建能力 四、写在最后 一、什么是低代码&#xff1f; 简单来说&#xff0c;低代码是一种用于应用程序开发的模块化方法&#xff0c;它能有效减少应用程序的开发时间。基于可重用的、组…

Nginx负载均衡 以及Linux前后端项目部署

一、Nginx简介 Nginx是一款高性能的开源Web服务器和反向代理服务器。它由俄罗斯的程序设计师Igor Sysoev创建&#xff0c;旨在解决传统Web服务器的性能限制问题。 Nginx采用事件驱动的架构和异步非阻塞的处理方式&#xff0c;使其能够处理大量并发连接&#xff0c;并具备良好…

机房精密空调发生内部设备通信故障不一会压缩机就停止工作,怎么处理?

环境: 山特AT-DA810U 精密空调 问题描述: 机房精密空调发生内部设备通信故障不一会压缩机就停止工作,怎么处理? 回风处不显示温湿度 解决方案: 1.进入诊断模式工程师密码333333 看到压缩机关闭了,强制输出测试一下压缩机正常 2.尝试更换温湿度传感器模块网口,重启…

1985-2022年全国各地级市绿色专利申请和授权数据

1985-2022年全国各地级市绿色专利申请和授权数据 1、时间&#xff1a;1985-2022年 2、指标&#xff1a;年份、地区、行政区划代码、所属省份、所属地域、绿色专利申请总量、绿色专利申请_发明专利、绿色专利申请_实用新型专利、绿色专利授权总量、绿色专利授权_发明专利、绿色…

IT老鸟给开发者升职加薪的小技巧

前言&#xff1a; 升职加薪对大多数人来说都是工作重要动力所在&#xff0c;但总存在“青出于蓝而胜于蓝”&#xff0c;后来人居上的情况。很多人不清楚&#xff0c;自己兢兢业业&#xff0c;任劳任怨&#xff0c;到头来还是得不到领导的重视&#xff0c;身边一起过来的同事都成…

学习笔记|两因素析因设计的方差分析|效应量|统计分析策略|《小白爱上SPSS》课程:SPSS第九讲 | 两因素析因设计的方差分析,超级详细

目录 学习目的软件版本原始文档两因素析因设计的方差分析一、实战案例二、统计策略三、SPSS操作1、正态性检验2、方差分析 四、结果解读Tips&#xff1a;效应量越大越好吗&#xff1f;统计分析策略 五、简单效应操作及结果1、SPSS操作2、结果解读 六、规范报告1、规范表格2、规…

[idea]关于idea开发乱码的配置

在JAVA开发中&#xff0c;一般统一设置为UTF-8的编码&#xff0c;包括但不限于开发工具、日志架构、虚拟机、文件编码等。常见配置如下&#xff1a; 1、IDEA工具 在idea64.exe.vmoptions、idea.exe.vmoptions中添加&#xff1a; -Dfile.encodingUTF-8 2、JAVA 运行在window…

web - 会话技术

文章目录 目录 文章目录 前言 一 . 会话 1.1 会话管理概述 1.2 会话管理实现手段 二 . Cookie 2.1 cookie概述 2.2 cookie的使用 2.3 Cookie的时效性 2.4 Cookie的提交路径 三 . Session 3.1 HttpSession概述 3.2 HttpSession的使用 3.3 HttpSession时效性 四 .…

9.MySQL索引的操作

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 索引操作 查询索引 创建主键索引 唯一索引的创建 普通索引的创建 全文索引的创建 删除索引 索引创建原则 索引操作 查询索引 第一种方法&#xff1a; show keys from 表名\G 我们了解其中几个就好。 第二种方法…

主从复制(gtid方式)

基于事务的Replication&#xff0c;就是利用GTID来实现的复制 GTID&#xff08;全局事务标示符&#xff09;最初由google实现&#xff0c;在MySQL 5.6中引入.GTID在事务提交时生成&#xff0c;由UUID和事务ID组成.uuid会在第一次启动MySQL时生成&#xff0c;保存在数据目录下的…

自动化测试的一些问题合集

问题1、 ipykernel_launcher.py: error: unrecognized arguments: usage: ipykernel_launcher.py [-h] [--id ID] [--test TEST] [--env ENV] ipykernel_launcher.py: error: unrecognized arguments: --ip127.0.0.1 --stdin9003 --control9001 --hb9000 --Session.signature_…

取消google账户银行卡支付信息Remove google payment method

在Google payment method里面&#xff08;网址https://payments.google.com/&#xff09;选择payment methods&#xff0c;然后移除即可。

SortableJS:vuedraggable实现元素拖放排序

文档&#xff1a;https://sortablejs.github.io/Sortable/github&#xff1a;https://github.com/SortableJS/SortableVue2: https://github.com/SortableJS/Vue.DraggableVue3: https://github.com/SortableJS/vue.draggable.nextnpm https://www.npmjs.com/package/vuedragga…

《低代码指南》——维格云机器人常见报错怎么解决?

在使用维格机器人调用维格表的API过程中,可能会出现机器人执行结果未达到预期的情况,此时可能是机器人运行出现了问题;通过点击这个机器人右上角的“运行历史”可以查看运行记录,通过对运行记录的分析,可以推断出问题所在,然后进行修改。 而对于运行历史的分析,主要是针…

Android NDK开发详解之调试和性能分析的ndk-gdb

Android NDK开发详解之调试和性能分析的ndk-gdb 要求用法选项 NDK 包含一个名为 ndk-gdb 的 Shell 脚本&#xff0c;可以启动命令行原生调试会话。偏好使用 GUI 的用户则应阅读在 Android Studio 中调试这篇文档。 要求 要运行命令行原生调试&#xff0c;必须满足以下要求&am…

【网络】网络层讲解

IP协议 前言正式开始IP协议报文第一行报文的封装和分离4位版本8位服务类型 第三行生存时间TTL检验和8位协议 32位源IP和32位目的IP第二行数据分片16位标识3位标志13位片偏移 网段划分网络分段的好处如何进行网络划分老版本的ABCDE新版本的CIDR特殊的IP地址IP地址的数量限制 私有…