Java实现微信小程序V3支付 (完整demo)

news2024/10/5 14:26:33

1. 微信小程序支付-开发者文档https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml

 

2. 导入依赖

<!--小程序支付 v3-->
<dependency>
	<groupId>com.github.wechatpay-apiv3</groupId>
	<artifactId>wechatpay-apache-httpclient</artifactId>
	<version>0.4.9</version>
</dependency>

 
3. 微信支付工具类

import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.PrivateKey;

/**
 * 微信支付工具类
 */
@Component
public class WxPayUtils {

    // 商户号
    public static final String mchId = "xxxxxxx";
    // AppID(小程序ID)
    public static final String appId = "xxxxxxx";
    // AppSecret(小程序密钥)
    public static final String appSecret = "xxxxxxx";
    // 授权
    public final static String grantType = "authorization_code";
    // APIv3密钥
    public final static String apiV3Key = "xxxxxxx";
    // 证书序列号 (从p12文件解析)
    public final static String serialnumber = "xxxxxxx";


    // 证书私钥
    public static final String privateKey = "xxxxxxx";


    /**
     * 获取私钥。
     */
    public static PrivateKey getPrivateKey() throws IOException {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new ByteArrayInputStream(privateKey.getBytes("utf-8")));
        return merchantPrivateKey;
    }
}

4. 微信支付URL工具类

public interface ConstantUtils {


    // JSAPI下单
    public final static String JSAPI_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
    // 支付通知
    public final static String NOTIFY_URL = "https://你的线上地址.com";
    // 关闭订单
    public final static String CLOSE_PAY_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close";
    // 查询订单 (根据商户订单号查询)
    public final static String QUERY_PAY_RESULT_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/";
}

5. 微信支付API v3 HttpClient (自动处理签名和验签)

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;


@Slf4j
@Component
@Order(3)
public class WechatPayaHttpclientUtils implements ApplicationRunner {

     // 商户API私钥
     public static PrivateKey merchantPrivateKey;
     // verifier
     public static Verifier verifier;
     // httpClient
     public static CloseableHttpClient httpClient;


    @Override
    public void run(ApplicationArguments args) {
        log.info("----------->构造微信支付API v3 HttpClient");
        createHttpClient();
    }


    /***
     * 微信支付API v3 HttpClient
     *
     * 自动处理签名和验签
     *
     * @return
     */
    public void createHttpClient() {
        try {

            merchantPrivateKey = WxPayUtils.getPrivateKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        try {
            // 向证书管理器增加需要自动更新平台证书的商户信息
            certificatesManager.putMerchant(WxPayUtils.mchId, new WechatPay2Credentials(WxPayUtils.mchId,
                    new PrivateKeySigner(WxPayUtils.serialnumber, merchantPrivateKey)), WxPayUtils.apiV3Key.getBytes(StandardCharsets.UTF_8));
            // ... 若有多个商户号,可继续调用putMerchant添加商户信息
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (HttpCodeException e) {
            e.printStackTrace();
        }
        try {
            // 从证书管理器中获取verifier
            verifier = certificatesManager.getVerifier(WxPayUtils.mchId);
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(WxPayUtils.mchId, WxPayUtils.serialnumber, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));
        // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
        httpClient = builder.build();
    }
}

 

6. controller

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.ruoyils.sy.order.domain.LsOrder;
import com.ruoyi.ruoyils.wx.pay.service.IWxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Api(value = "微信-支付", tags = {"微信-支付"})
@RestController
@RequestMapping("/ls/wx/pay")
public class WxPayController extends BaseController {

    @Autowired
    private IWxPayService wxPayService;


    /**
     * jsapi下单
     *
     * @param lsOrder   订单
     * @return
     */
    @ApiOperation("统一下单")
    @PostMapping(value = "/payment")
    public AjaxResult payment(@RequestBody LsOrder lsOrder) {
        return wxPayService.addOrder(lsOrder);
    }


    /**
     * 支付通知
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/notifyUrl")
    public AjaxResult notifyUrl(HttpServletRequest request, HttpServletResponse response) {
        return AjaxResult.success(wxPayService.notifyUrl(request, response));
    }


    /**
     * 关闭订单
     *
     * 当用户10分钟内未支付,系统自动关闭微信支付订单
     *
     * @param orderNo   订单号
     * @return
     */
    @GetMapping("/closePayOrder")
    public AjaxResult closePayOrder(String orderNo) {
        return AjaxResult.success(wxPayService.closePayOrder(orderNo));
    }

}

7. service

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.ruoyils.exception.MyException;
import com.ruoyi.ruoyils.sy.append.domain.LsAppend;
import com.ruoyi.ruoyils.sy.append.mapper.LsAppendMapper;
import com.ruoyi.ruoyils.sy.order.domain.LsOrder;
import com.ruoyi.ruoyils.sy.order.mapper.LsOrderMapper;
import com.ruoyi.ruoyils.sy.order.service.impl.LsOrderServiceImpl;
import com.ruoyi.ruoyils.sy.product.domain.LsProduct;
import com.ruoyi.ruoyils.sy.product.mapper.LsProductMapper;
import com.ruoyi.ruoyils.utils.*;
import com.ruoyi.ruoyils.wx.pay.service.IWxPayService;
import com.ruoyi.ruoyils.wx.user.domain.LsUser;
import com.ruoyi.ruoyils.wx.user.mapper.LsUserMapper;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.Signature;
import java.util.*;

@Order(5)
@Slf4j
@Service
public class WxPayServiceImpl implements IWxPayService {

    @Autowired
    private LsOrderMapper orderMapper;
    @Autowired
    private LsUserMapper lsUserMapper;
    @Autowired
    private LsProductMapper lsProductMapper;
    @Autowired
    private LsAppendMapper lsAppendMapper;


    /**
     * 立即下单
     *
     * @param lsOrder 订单
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult addOrder(LsOrder lsOrder) {
            
            // TODO 计算你的业务订单
            
            // 生成订单
            int i = orderMapper.insertLsOrder(lsOrder);
            if (i > 0) {
                // 调起支付
                AjaxResult payment = this.payment(lsOrder);
                return payment;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return AjaxResult.error("下单失败 !");
    }


    /**
     * 调起支付
     *
     * @param lsOrder
     * @return
     */

    @Override
    public AjaxResult payment(LsOrder lsOrder) {
        try {
            JSONObject order = new JSONObject();
            // 应用ID
            order.put("appid",WxPayUtils.appId);
            // 商户号
            order.put("mchid",WxPayUtils.mchId);
            // 商品描述
            order.put("description",lsOrder.getProductName());
            // 订单号
            order.put("out_trade_no",lsOrder.getOrderNo());
            // 通知地址
            order.put("notify_url",ConstantUtils.NOTIFY_URL+"/ls/wx/pay/notifyUrl");
            /**订单金额*/
            JSONObject amount = new JSONObject();
            // 总金额 (默认单位分)
//            amount.put("total",lsOrder.getTotalPrice().intValue()*100);
            amount.put("total",1);
            // 货币类型
            amount.put("currency","CNY");
            order.put("amount",amount);

            /**支付者*/
            JSONObject payer = new JSONObject();
            LsUser user = SpringUtils.getBean(LsUserMapper.class).selectLsUserById(lsOrder.getUserId());
            // 用户标识
            payer.put("openid",user.getOpenid());
            order.put("payer",payer);

            // 微信httpClient
            CloseableHttpClient httpClient = WechatPayaHttpclientUtils.httpClient;
            if (httpClient == null) {
                log.info("预下单请求失败");
                return AjaxResult.error("预下单失败,请重试,无法连接微信支付服务器!");
            }

            HttpPost httpPost = new HttpPost(ConstantUtils.JSAPI_URL);
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-type","application/json; charset=utf-8");
            httpPost.setEntity(new StringEntity(order.toJSONString(), "UTF-8"));
            // 后面跟使用Apache HttpClient一样
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String bodyAsString = EntityUtils.toString(response.getEntity());

            JSONObject bodyAsJSON = JSONObject.parseObject(bodyAsString);
            String message = bodyAsJSON.getString("message");
            // 返回code, 说明请求失败
            if (bodyAsJSON.containsKey("code")) {
                log.info("预下单请求失败{}", message);
                return AjaxResult.error("预下单失败,请重试!" + message);
            }

            // 返回预支付id
            final String prepay_id = bodyAsJSON.getString("prepay_id");
            if (StringUtils.isEmpty(prepay_id)) {
                log.info("预下单请求失败{}", message);
                return AjaxResult.error("预下单失败,请重试!" + message);
            }

            LsOrder preOrder = new LsOrder();
            preOrder.setId(lsOrder.getId());
            preOrder.setPrepayId(prepay_id);
            orderMapper.updateLsOrder(preOrder);

            // JSAPI调起支付API: 此API无后台接口交互,需要将列表中的数据签名
            // 随机字符串
            final String nonceStr = RandomNumberUtils.getRandomString(32,false);
            // 时间戳
            String timeStamp = String.valueOf(System.currentTimeMillis());
            /*签名*/
            StringBuilder sb = new StringBuilder();
            sb.append(WxPayUtils.appId + "\n"); //小程序appId
            sb.append(timeStamp + "\n"); //时间戳
            sb.append(nonceStr + "\n"); //随机字符串
            sb.append("prepay_id=" + prepay_id + "\n"); //订单详情扩展字符串
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(WechatPayaHttpclientUtils.merchantPrivateKey);
            signature.update(sb.toString().getBytes("UTF-8"));
            byte[] signBytes = signature.sign();
            String paySign = Base64.encode(signBytes);

            JSONObject params = new JSONObject();
            params.put("appId", WxPayUtils.appId);
            params.put("timeStamp", timeStamp);
            params.put("nonceStr", nonceStr);
            params.put("package", "prepay_id="+prepay_id);
            params.put("signType", "RSA");
            params.put("paySign", paySign);

            return AjaxResult.success(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error("预下单失败,请重试!");
    }

    /**
     * 支付通知
     *
     * @param servletRequest
     * @param response
     * @return
     */
    @Override
    public AjaxResult notifyUrl(HttpServletRequest servletRequest, HttpServletResponse response) {
        log.info("----------->微信支付回调开始");
        Map<String, String> map = new HashMap<>(12);
        String timeStamp = servletRequest.getHeader("Wechatpay-Timestamp");
        String nonce = servletRequest.getHeader("Wechatpay-Nonce");
        String signature = servletRequest.getHeader("Wechatpay-Signature");
        String certSn = servletRequest.getHeader("Wechatpay-Serial");
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(servletRequest.getInputStream()))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            String obj = stringBuilder.toString();
            log.info("支付回调请求参数:{},{},{},{},{}", obj, timeStamp, nonce, signature, certSn);

            // 从证书管理器中获取verifier
            Verifier verifier = WechatPayaHttpclientUtils.verifier;

            String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
            NotificationRequest request = new NotificationRequest.Builder().withSerialNumber(sn)
                    .withNonce(nonce)
                    .withTimestamp(timeStamp)
                    .withSignature(signature)
                    .withBody(obj)
                    .build();
            NotificationHandler handler = new NotificationHandler(verifier, WxPayUtils.apiV3Key.getBytes(StandardCharsets.UTF_8));
            // 验签和解析请求体
            Notification notification = handler.parse(request);
            JSONObject bodyAsJSON = JSON.parseObject(notification.getDecryptData());
            log.info("支付回调响应参数:{}", bodyAsJSON.toJSONString());
            //做一些操作
            if (bodyAsJSON != null) {
                //如果支付成功
                String tradeState = bodyAsJSON.getString("trade_state");
                if("SUCCESS".equals(tradeState)){
                    //拿到商户订单号
                    String outTradeNo = bodyAsJSON.getString("out_trade_no");
                    JSONObject amountJson = bodyAsJSON.getJSONObject("amount");
                    Integer payerTotal = amountJson.getInteger("payer_total");
                    LsOrder order = orderMapper.selectLsOrderByOrderNo(outTradeNo);
                    if(order != null){
                        if(order.getStatus() == 1){
                            //如果支付状态为1 说明订单已经支付成功了,直接响应微信服务器返回成功
                            response.setStatus(200);
                            map.put("code", "SUCCESS");
                            map.put("message", "SUCCESS");
                            response.setHeader("Content-type", ContentType.JSON.toString());
                            response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
                            response.flushBuffer();
                        }
                        //验证用户支付的金额和订单金额是否一致
                        if(payerTotal.equals(order.getTotalPrice())){
                            //修改订单状态
                            String successTime = bodyAsJSON.getString("success_time");
                            order.setStatus(1);
                            order.setPaymentTime(DateUtils.rfcToDate(successTime));
                            orderMapper.updateLsOrder(order);
                            //响应微信服务器
                            response.setStatus(200);
                            map.put("code", "SUCCESS");
                            map.put("message", "SUCCESS");
                            response.setHeader("Content-type", ContentType.JSON.toString());
                            response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
                            response.flushBuffer();
                        }
                    }
                }
            }
            response.setStatus(500);
            map.put("code", "FAIL");
            map.put("message", "签名错误");
            response.setHeader("Content-type", ContentType.JSON.toString());
            response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("微信支付回调失败", e);
        }
        return AjaxResult.error("微信支付回调失败");
    }

    /**
     * 关闭订单
     *
     * @param orderNo
     * @return
     */
    @Override
    public String closePayOrder(String orderNo) {
        JSONObject obj = new JSONObject();
        // 直连商户号
        obj.put("mchid", WxPayUtils.mchId);
        // 请求地址
        String closeOrderUrl = ConstantUtils.CLOSE_PAY_ORDER_URL.replace("{out_trade_no}", orderNo);

        log.info("关闭微信订单--请求参数{}" , obj.toJSONString());
        HttpPost httpPost = new HttpPost(closeOrderUrl);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        httpPost.setEntity(new StringEntity(obj.toJSONString(), "UTF-8"));
        String bodyAsString ;

        // 微信httpClient
        CloseableHttpClient httpClient = WechatPayaHttpclientUtils.httpClient;
        try {
            if(httpClient == null){
                log.info("关闭订单失败,请重试,无法连接微信支付服务器!");
            }
            //执行请求
            CloseableHttpResponse response = httpClient.execute(httpPost);
            //状态码
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 204) {
                //关闭订单成功!
                log.info("关闭微信订单--关闭订单成功orderCode:{}!", orderNo);
                LsOrder order = new LsOrder();
                order.setOrderNo(orderNo);
                // 取消订单
                order.setStatus(0);
                orderMapper.updateLsOrderByOrderAndStatus(order);
            }else if(statusCode == 202){
                //用户支付中,需要输入密码
                log.info("关闭微信订单--用户支付中,需要输入密码,暂时不做处理!");
            }else{
                log.info("关闭微信订单--关闭支付订单失败,出现未知原因{}", EntityUtils.toString(response.getEntity()));
            }
        } catch (IOException e) {
            log.info("关闭微信订单--关闭订单失败{}", e.getMessage());
        }
        return null;
    }

    /**
     * 订单查询 (定时查询订单, 修改订单状态)
     *
     * @return
     */
    @Scheduled(cron="0/10 * * * * ?")
    public void queryOrder() {

        LsOrder od = new LsOrder();
        od.setStatus(3); //未支付
        List<LsOrder> list = SpringUtils.getBean(LsOrderMapper.class).selectLsOrderList(od);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        try {
            for (LsOrder lsOrder : list) {
                // 根据商户订单号查询
                URIBuilder uriBuilder = new URIBuilder(ConstantUtils.QUERY_PAY_RESULT_URL+lsOrder.getOrderNo());
                uriBuilder.setParameter("mchid", WxPayUtils.mchId);

                HttpGet httpGet = new HttpGet(uriBuilder.build());
                httpGet.addHeader("Accept", "application/json");

                CloseableHttpClient httpClient = WechatPayaHttpclientUtils.httpClient;
                if (httpClient == null) {
                    return;
                }
                CloseableHttpResponse response = httpClient.execute(httpGet);
                String bodyAsString = EntityUtils.toString(response.getEntity());
                JSONObject data = JSON.parseObject(bodyAsString);
                log.info("微信订单查询:{}", data);

                // 商户订单号
                String outTradeNo = data.getString("out_trade_no");
                // 交易状态 SUCCESS:支付成功, REFUND:转入退款, NOTPAY:未支付, CLOSED:已关闭
                String tradeState = data.getString("trade_state");
                // 支付完成时间
                String successTime = data.getString("success_time");
                Date date = DateUtils.rfcToDate(successTime);


                if (StringUtils.isNotEmpty(outTradeNo) && StringUtils.isNotEmpty(tradeState)) {
                    switch (tradeState) {
                        case "SUCCESS":
                            log.info("支付成功商户订单号: {}",outTradeNo);
                            lsOrder.setStatus(1);
                            lsOrder.setPaymentTime(date);
                            orderMapper.updateLsOrder(lsOrder);
                            break;
                        case "REFUND":
                            break;
                        case "NOTPAY":
                            break;
                        case "CLOSED":
                            log.info("已关闭商户订单号: {}",outTradeNo);
                            lsOrder.setStatus(0);
                            orderMapper.updateLsOrder(lsOrder);
                            break;
                    }
                } else {
                    log.info(data.getString("message"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

8. 返回给前端调起支付的必要参数

{
    "msg": "操作成功",
    "code": 200,
    "data": {
        "timeStamp": "1692334223808",
        "package": "prepay_id=wx18125024326178678d4e07673e277c0000",
        "paySign": "ocI64smXYkantoHEIkv7fibP0Y83pUmoVN1pQAjrJnFRI75sXCmQt09emPMhZJ+ujuemaGinJdJjmvGZv1JFoWvGSaMv8imDxOQV2EBr9QI+gybtUyC57+H2PhjXIR4gF0M8n7yv6Q9TA+7EIfpXOTaMJjDzM4AkFhAwz/quUAAEJVPLuaMsyF1xqi1qSY9AnE309YhqVG6ETDbZeP9/fuGCs9gD1HdD14HF4BndU696wR4TQdoiTzIyOokrE21oZLdK6Tp6sBPj2mGiIFX8viEHxq8GWOEMOIQXlr4NId4hrYA1Nn6xLk2Ka75t2t8L5V//3rWmbGSOaE5nrkeJcg==",
        "appId": "xxxxxxxxxxxxxx",
        "signType": "RSA",
        "nonceStr": "KFW6FBHHDMALH1A39FM07HKXM7I0T1GR"
    }
}

 

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

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

相关文章

精密、CMOS、轨到轨输入/输出、宽带运算放大器MS8601/8602/8604

产品简述 MS8601/MS8602/MS8604 分别是单 / 双 / 四通道、轨到轨输入和输出、 单电源放大器&#xff0c;具有极低的失调电压和宽信号带宽。它采用 1.8V 至 5V 单电 源&#xff08; 0.9 V 至 2.5 V 双电源&#xff09;供电。 MS8601/MS8602/MS8604 低失调、极低的输入偏置…

02__models

LangChain提供两种封装的模型接口 1.大规模语言模型&#xff08;LLM&#xff09;&#xff1a;输入文本字符串&#xff0c;返回文本字符串 2.聊天模型&#xff1a;基于一个语言模型&#xff0c;输入聊天消息列表&#xff0c;返回聊天消息 Langchain的支持OpenAI、ChatGLM、Hu…

Minjourney 参数详解(MJ参数)

官方地址&#xff1a; Midjourney Parameter ListParameters are added to a prompt to change how an image generates. Parameters can change an images aspect ratios, model version, upscaler, and more.https://docs.midjourney.com/docs/parameter-list官方原文&#…

更改计算机睡眠时间

控制面板–>系统和安全–>电源选项下的更改计算机睡眠时间 如果关闭显示器时间小于使计算机进入睡眠状态时间&#xff0c;时间先到达关闭显示器时间&#xff0c;显示器关闭&#xff0c;这时电脑还在正常工作状态。如果此时敲击键盘显示器出现画面&#xff0c;无需输入密…

最小化安装移动云大云操作系统--BCLinux-R8-U8-Server-x86_64-230802版

CentOS 结束技术支持&#xff0c;转为RHEL的前置stream版本后&#xff0c;国内开源Linux服务器OS生态转向了开源龙蜥和开源欧拉两大开源社区&#xff0c;对应衍生出了一系列商用Linux服务器系统。BC-Linux V8.8是中国移动基于龙蜥社区Anolis OS 8.8版本深度定制的企业级X86服务…

Unable to create tempDir. java.io.tmpdir is set to ./tmp

项目场景&#xff1a; 程序启动时报错&#xff1a;Application run failed org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to create tempDir…

第07天 Static关键字作用及用法

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

小航助学Python编程NOC模拟卷(第1套)(含题库答题软件账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSD…

C++ STL序列式容器(详解)

STL基础 C STL基本组成&#xff08;6大组件13个头文件&#xff09; 通常认为&#xff0c;STL 是由容器、算法、迭代器、函数对象、适配器、内存分配器这 6 部分构成&#xff0c;其中后面 4 部分是为前 2 部分服务的&#xff0c;它们各自的含义如表 1 所示。 ​ 表 1 STL 组成…

石头IT

石头是地球上最常见的矿石之一&#xff0c;它由天然矿物颗粒组成。石头可以有不同的形状&#xff0c;大小和颜色&#xff0c;取决于其中的矿物组成和地质过程。石头可以从地球表面的岩石中形成&#xff0c;也可以从火山活动或陨石撞击中形成。 石头是一种非常坚固和耐用的材料…

BifroMQ:五分钟了解百度开源旗下消息中间件

BifroMQ 并不是一个独立的公司&#xff0c;而是由一家名为 "Bifrost" 的公司开发的一款产品。Bifrost 公司成立于 2014 年&#xff0c;总部位于中国北京&#xff0c;是一家专注于开源技术的公司。当时 Bifrost 公司的创始人陈明发起了开源项目 "iProven"&a…

综合能源系统(7)——综合能源综合评估技术

综合能源系统关键技术与典型案例  何泽家&#xff0c;李德智主编 综合能源系统是多种能源系统非线性耦合的、多时间与空间尺度耦合的“源-网-荷一储”一体化系统&#xff0c;通过能源耦合、多能互补&#xff0c;能够实现能源的高效利用&#xff0c;并提高新能源的利用水平。对…

Power Basic 入门-4

前面我们叙述了power的一些基本概念&#xff0c;其中&#xff0c;对于switching power计算的部分&#xff0c;我们发现了一些correlation问题。 接下来&#xff0c;解释一下这个问题 首先&#xff0c;我们要报一下cell power pt_shell> report_power -cell_power inst_q_…

openLayers实战(八):坐标系及其转换

坐标系介绍 EPSG: 3857 --web地图&#xff0c;基于球体的、web墨卡托投影&#xff08;伪墨卡托投影Pseudo-Mercator&#xff09;的投影坐标系&#xff0c;范围为纬度85度以下&#xff0c;由于google地图最先使用而成为事实标准。至今&#xff0c;大多互联网地图都使用EPSG3857&…

分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测

分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测 目录 分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分…

数据结构:二叉树的递归实现(C实现)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》 文章目录 前言一、树的概念二、二叉树二叉树的概念二叉树的性质 三、二叉树链式结构实现二叉树节点定义创建二叉树节点遍历二叉树先序遍历二叉树(BinaryTreePrevOrder)中序遍历二叉树(BinaryTree…

论文阅读——Imperceptible Adversarial Attack via Invertible Neural Networks

Imperceptible Adversarial Attack via Invertible Neural Networks 作者&#xff1a;Zihan Chen, Ziyue Wang, Junjie Huang*, Wentao Zhao, Xiao Liu, Dejian Guan 解决的问题&#xff1a;虽然视觉不可感知性是对抗性示例的理想特性&#xff0c;但传统的对抗性攻击仍然会产…

java面试基础 -- 普通类 抽象类 接口

目录 抽象类语法 抽象类特性 普通类 & 抽象类 抽象类 & 接口 什么是接口 语法 接口方法 变量 接口特性 抽象类&接口的区别 抽象类语法 在Java中&#xff0c;一个类如果被 abstract 修饰称为抽象类&#xff0c;抽象类中被 abstract 修饰的方法称为抽象…

python-03(入门基础篇3——字符串 的 基本常见语法 以及 format的用法)

python-03&#xff08;入门基础篇3——字符串 的 基本常见语法 以及 format的用法&#xff09; 1. 前言1.1 体验python入门1.2 官网参考 2. 字符串简单入门2.1 简单介绍2.2 拼接字符串&#xff08;&#xff09;和 重复字符串&#xff08;*&#xff09;2.3 相邻字符串自动拼接2.…

凭空销毁千万,揭秘nd4.eth大佬背后的故事

文/章鱼哥 出品/陀螺财经 在加密社区&#xff0c;千万资产的销毁&#xff0c;就在弹指之间&#xff0c;好似一场行为艺术。 上周&#xff0c;nd4.eth域名的不明持有者在没有任何公开解释的前提下销毁了价值约800余万美元的加密货币和高价值蓝筹NFT&#xff0c;引起了看客们的关…