当前位置: 首页 > news >正文

spring boot + uniapp 微信公众号 jsapi 支付

后端支付类

package com.ruoyi.coupon.payment;import com.google.gson.Gson;
import com.ruoyi.coupon.payment.dto.PayParamJsapiDto;
import com.ruoyi.coupon.payment.dto.RefundParam;
import com.ruoyi.coupon.service.ICouponConfigService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.model.TransactionAmount;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.*;
import java.util.*;@Service
public class WeChatJsapiPayment {private static final String mchId = "165"; // 商户号private static final String mchSerialNo = "12C5F95"; // 商户证书序列号//商户私钥 //https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_1.shtmlprivate static final String privateKey = "-----BEGIN PRIVATE KEY-----" +"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOo7rFC6cJF+kd" +"7cPFkmrHlbdihgznK2u5v2CDoSClwrY1hGE81VJMHjHic03Ky0Hx1lCZh+hOCZXk" +"4mnTnbeUlvq/6E6I6gexsM9ww6nz0YbPRZuNPPxBmP1rqKzlZO7LiLvIwg8x3cOr" +"qB4uPCo5Eh0Ty3r1kygfEXDyWEHWRYx1JVesmcxBp2n8HkfIpNA3tyPFnTFJEI4W" +"/7T4ScoSlRRUsYNrg0oox683HgFXWE9fAJloyt35EHPoBEx6gUGKC9Gm1luJNrSb" +"9GAQCPLVgtr3hq0kQHvVKcKsgpzPJA5G20bTM1X9Yo/nr+rt+HFZpbaNvviuhXg7" +"EvajkeprAgMBAAECggEAUXVTzBei2j/VwtmW4kys0U7gwvMLJRoF1mxt9JXRE+cl" +"AwXTezKwxZblnVpM4VOtBFOy5EMiPZkjwN3MUAKNewLliD9grjJrpA2KSO6pEZeY" +"aB8NiejvnEBeLlGJDsjyJcQaGrL9YHAGkaWteBZ5opPUaJg/OY2wNEcg2jgWhAui" +"eTqocUEnbowDCFlpHEJmAJKxuaLaV39Wad1jKs9N9CiqYyVNfNoeZJ7LSHekrz6v" +"SOVD8nz3y/1evf4LqkaIjLJwTS9UXVZuKjlyLcjsEpGf4X3cZ7hI/wJEqXDqKSL8" +"cgbnkZTI6YI32ukAIne/d3AOsRkbYomR26g3cqpeqQKBgQD9bxwYm+Z73SrfCJte" +"8Tj9ejrBWcAU1r8p1uu7kiL2gU0RVxwzBe0QNhLUybP5ciONzAtkS6/NPLkHU6HQ" +"frb9JqoipC6LT7c2R4kR+4wcLH9lbiscljPUji04sEEMzUrLWjwcAwLjlCNbqZ4m" +"UJ2y4skFFzVEa6a8uO7qX5qFpQKBgQDQu1Sgrhb2Yby/YuJyq2j8k5BRiHcjLmUI" +"Pi1uIq0lUof4F61EkFuua+bsr+oaiQxhqKIkPbURnjdkEG2bC5K/n+f2BbOFOfSz" +"14ygBoZaRGZvoS56xOETh9ao9sLCsQJgz1E3gwYpAIbh6DBvoU8w0prL/O0gbAC/" +"CywSvL1SzwKBgHJ413X+JTNZiN3JI3TU/Grx5Mwk3/AJt7sMStokfgpeCROGB0S8" +"roGeCw92NAa+GXUY7yRUU4oenWzDx9lHAxyBdGPFSQi/7v9jfHRU7MplBv4nru1w" +"ouSle6OZaSiBKgGENpZofcuRxA7JJJgl3bVJXocgHn1TKrMfzTqsCD3JAoGBAK8S";// 你的微信支付平台证书private static final String apiV3Key = "f2f4667bfeab441";//公众号appIdprivate static final String appid="wx29d5";private static final String secret = "58be861a9f6";public static Map<String,RSAAutoCertificateConfig> config=new HashMap<>();@Autowiredprivate ICouponConfigService couponConfigService;/*** 获取jsapi服务类* @return*/public JsapiService getJsapiService(){RSAAutoCertificateConfig rsaAutoCertificateConfig = config.get(this.mchId);if(rsaAutoCertificateConfig == null){RSAAutoCertificateConfig build = new RSAAutoCertificateConfig.Builder().merchantId(this.mchId).privateKey(this.privateKey)//.privateKeyFromPath(WxConfig.privateKeyPath).merchantSerialNumber(this.mchSerialNo).apiV3Key(this.apiV3Key).build();config.put(this.mchId,build);rsaAutoCertificateConfig = build;}JsapiService service = new JsapiService.Builder().config(rsaAutoCertificateConfig).build();return service;}/*** 进行支付* @param payParam* @return*/public String pay(PayParamJsapiDto payParam) {String apiUrl = couponConfigService.getValue("online_domain");JsapiService jsapiService = getJsapiService();PrepayRequest request = new PrepayRequest();Amount amount = new Amount();amount.setTotal((int)(Double.parseDouble(payParam.getAmount().toPlainString())*100));//amount.setTotal(1);request.setAmount(amount);request.setAppid(payParam.getAppid());request.setMchid(payParam.getMerchantId());request.setDescription(payParam.getDescription());request.setNotifyUrl(apiUrl +"api" + "/payment/weChatOfficialAccounts/payment/notify");//这个回调url必须是https开头的request.setOutTradeNo(payParam.getOutTradeNo());Payer payer = new Payer();payer.setOpenid(payParam.getOpenid());request.setPayer(payer);//设置回传参数Gson gson=new Gson();request.setAttach(gson.toJson(payParam.getParam()));PrepayResponse prepay = jsapiService.prepay(request);String prepayid=prepay.getPrepayId();return prepayid;}/** 商户订单号查询订单 */public Transaction queryOrderByOutTradeNo(String orderNum) {JsapiService jsapiService = getJsapiService();QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();request.setOutTradeNo(orderNum);// 调用request.setXxx(val)设置所需参数,具体参数可见Request定义// 调用接口return jsapiService.queryOrderByOutTradeNo(request);}/*** 支付成功验签* @param request* @return*/public Map paySuccessCheck(HttpServletRequest request) {/*Config config =new RSAAutoCertificateConfig.Builder().merchantId(dto.getWechatpayMchid()).privateKey(dto.getWechatpayPrivatekey()).merchantSerialNumber(dto.getWechatpayMchserialno()).apiV3Key(dto.getWechatpayApiv3key()).build();*/RSAAutoCertificateConfig config1 = config.get(this.mchId);if(config1 == null){RSAAutoCertificateConfig build = new RSAAutoCertificateConfig.Builder().merchantId(this.mchId).privateKey(this.privateKey)//.privateKeyFromPath(WxConfig.privateKeyPath).merchantSerialNumber(this.mchSerialNo).apiV3Key(this.apiV3Key).build();config.put(this.mchId,build);config1 = build;}// 从请求头中获取信息String timestamp                        = request.getHeader("Wechatpay-Timestamp");String nonce                            = request.getHeader("Wechatpay-Nonce");String signature                        = request.getHeader("Wechatpay-Signature");String singType                         = request.getHeader("Wechatpay-Signature-Type");String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");String requestBody = getRequestBody(request);// 构造 RequestParamRequestParam requestParam = new RequestParam.Builder().serialNumber(wechatPayCertificateSerialNumber).nonce(nonce).signature(signature).signType(singType).timestamp(timestamp).body(requestBody).build();// 初始化解析器 NotificationParserNotificationParser parser = new NotificationParser((NotificationConfig) config1);// 这个Transaction是微信包里面的Transaction decryptObject = parser.parse(requestParam, Transaction.class);TransactionAmount amount = decryptObject.getAmount();String outTradeNo = decryptObject.getOutTradeNo();String attach = decryptObject.getAttach();Map map=new HashMap();map.put("amount",amount.getTotal());map.put("outTradeNo",outTradeNo);map.put("attach",attach);return map;}// 获取请求头里的数据private String getRequestBody(HttpServletRequest request) {StringBuffer sb = new StringBuffer();try (ServletInputStream inputStream = request.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) {String line;while ((line = reader.readLine()) != null) {sb.append(line);}} catch (IOException e) {System.out.println("读取数据流异常:"+e);}return sb.toString();}/*** 组装支付参数* @param prepayId* @return*/public Map getPayParameter(String prepayId){Map<String,String> map=new HashMap<>();map.put("appId",this.appid);map.put("timeStamp",String.valueOf(new Date().getTime()));map.put("nonceStr", UUID.randomUUID().toString().replace("-",""));map.put("package","prepay_id="+prepayId);map.put("signType","RSA");String s = map.get("appId") + "\n" + map.get("timeStamp") + "\n" + map.get("nonceStr") + "\n" + map.get("package") + "\n";try {PrivateKey privateKey1 = PemUtil.loadPrivateKeyFromString(this.privateKey);Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(privateKey1);sign.update(s.getBytes("utf-8"));String string = Base64.getEncoder().encodeToString(sign.sign());map.put("paySign",string);return map;} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (SignatureException e) {e.printStackTrace();}return null;}/*** 公众号 code 换取 openid* @param code* @return*/public String getOpenId(String code) {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + this.appid + "&secret=" + this.secret + "&code=" + code + "&grant_type=authorization_code").build();try {Response response = client.newCall(request).execute();String string = response.body().string();//System.out.println(string);Gson gson = new Gson();Map map = gson.fromJson(string, Map.class);/*** {* 	"session_key": "G4YmjKXmPsqjDFdtcjp/9A==",* 	"openid": "o27Z36yx16I4EF84dpTslNdVhsQY"* }*/return (String) map.get("openid");} catch (IOException e) {e.printStackTrace();}return null;}/*** 申请退款* @param refundParam*/public void refundOrder(RefundParam refundParam) {String apiUrl = couponConfigService.getValue("online_domain");BigDecimal bigDecimal = new BigDecimal(100);int total = bigDecimal.multiply(new BigDecimal(refundParam.getTotal())).intValue();int refund = bigDecimal.multiply(new BigDecimal(refundParam.getRefund())).intValue();Config config =new RSAAutoCertificateConfig.Builder().merchantId(mchId).privateKey(privateKey).merchantSerialNumber(mchSerialNo).apiV3Key(apiV3Key).build();RefundService service = new RefundService.Builder().config(config).build();//生成随机退款订单号String s = UUID.randomUUID().toString().replace("-","");CreateRequest request = new CreateRequest();//金额信息AmountReq amount = new AmountReq();amount.setCurrency("CNY");amount.setTotal(Long.valueOf(total));amount.setRefund(Long.valueOf(refund));request.setAmount(amount);request.setOutTradeNo(refundParam.getOutTradeNo());request.setOutRefundNo(s);//request.setNotifyUrl("http://egevdr.natappfree.cc" + "/payment/weChatPay/refund/notify");request.setNotifyUrl(apiUrl +"api" + "/payment/weChatOfficialAccounts/refund/notify");//发送请求Refund refund1 = service.create(request);}public Map refundSuccessCheck(HttpServletRequest request) {Config config =new RSAAutoCertificateConfig.Builder().merchantId(mchId).privateKey(privateKey).merchantSerialNumber(mchSerialNo).apiV3Key(apiV3Key).build();// 从请求头中获取信息String timestamp                        = request.getHeader("Wechatpay-Timestamp");String nonce                            = request.getHeader("Wechatpay-Nonce");String signature                        = request.getHeader("Wechatpay-Signature");String singType                         = request.getHeader("Wechatpay-Signature-Type");String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");String requestBody = getRequestBody(request);// 构造 RequestParamRequestParam requestParam = new RequestParam.Builder().serialNumber(wechatPayCertificateSerialNumber).nonce(nonce).signature(signature).signType(singType).timestamp(timestamp).body(requestBody).build();// 初始化解析器 NotificationParserNotificationParser parser = new NotificationParser((NotificationConfig) config);// 这个Transaction是微信包里面的RefundNotification decryptObject = parser.parse(requestParam, RefundNotification.class);com.wechat.pay.java.service.refund.model.Amount amount = decryptObject.getAmount();String outTradeNo = decryptObject.getOutTradeNo();Map map=new HashMap();map.put("amount",amount.getTotal());map.put("outTradeNo",outTradeNo);return map;}
}

后端下单

String openId=weChatJsapiPayment.getOpenId(code);PayParamJsapiDto payParam = new PayParamJsapiDto();//payParam.setSubject(StringUtils.isBlank(byId2.getGoodsName())?byId2.getGoodsSuffixName():byId2.getGoodsName());payParam.setDescription(StringUtils.isBlank(byId2.getGoodsName())?byId2.getGoodsSuffixName():byId2.getGoodsName());payParam.setOutTradeNo(couponOrder.getOrderNum());//payParam.setAmount(new BigDecimal("0.01"));payParam.setAmount(new BigDecimal(price.toString()));payParam.setAppid("wx29d50");payParam.setMerchantId("1651");payParam.setOpenid(openId);String pay = weChatJsapiPayment.pay(payParam);Map payParameter = weChatJsapiPayment.getPayParameter(pay);

后端退款

RefundParam param=new RefundParam();param.setOutTradeNo(byId.getOrderNum());param.setBody("卡券权益退款");param.setRefund(byId.getPayMoney().toString());param.setTotal(byId.getPayMoney().toString());//微信退款weChatJsapiPayment.refundOrder(param);

下单和退款的dto

package com.ruoyi.coupon.payment.dto;import lombok.Data;/*** 退款参数封装*/
@Data
public class RefundParam {//订单号private  String outTradeNo;//本次退款金额金额private  String refund;//订单总金额private  String total;//备注private  String body;
}
package com.ruoyi.coupon.payment.dto;import lombok.Data;import java.math.BigDecimal;
@Data
public class PayParamJsapiDto {private String appid;private String merchantId;//支付描述private String description;private String openid;private String outTradeNo;//需支付金额private BigDecimal amount;private PassbackParamsJsapiDto param;
}
package com.ruoyi.coupon.payment.dto;import lombok.Data;@Data
public class PassbackParamsJsapiDto {
}

后端支付回调类

package com.ruoyi.api.controller.coupon.payment.rest;import com.ruoyi.coupon.payment.WeChatJsapiPayment;
import com.ruoyi.coupon.payment.WeChatPayment;
import com.ruoyi.coupon.payment.event.PaymentEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;/*** 商城支付项微信支付的回调接口*/
@Slf4j
@RestController
@RequestMapping("/payment/weChatOfficialAccounts")
public class WeChatOfficialAccountsNotify {@Autowiredprivate ApplicationEventPublisher publisher;@Autowiredprivate WeChatJsapiPayment weChatJsapiPayment;/*** 微信支付/充值回调*/@PostMapping("/payment/notify")public ResponseEntity.BodyBuilder  renotify(HttpServletRequest request) {Map map = weChatJsapiPayment.paySuccessCheck(request);Integer amount = (Integer)map.get("amount");String outTradeNo = (String)map.get("outTradeNo");String attach = (String)map.get("attach");Map<String, Object> map1 = new HashMap<>();//将附加信息 attach 解析到 map1 中,因为现在没有传递任何参数,所以没有解析BigDecimal divide = new BigDecimal(amount).divide(new BigDecimal("100"));publisher.publishEvent(new PaymentEvent(this, outTradeNo,0,map1,divide.toString()));return ResponseEntity.status(HttpStatus.OK);}/*** 微信退款回调*/@PostMapping("/refund/notify")public ResponseEntity.BodyBuilder parseRefundNotifyResult(HttpServletRequest request) {Map map = weChatJsapiPayment.refundSuccessCheck(request);Long amount = (Long)map.get("amount");String outTradeNo = (String)map.get("outTradeNo");BigDecimal divide = new BigDecimal(amount).divide(new BigDecimal("100"));publisher.publishEvent(new PaymentEvent(this, outTradeNo,1,null,divide.toString()));return ResponseEntity.status(HttpStatus.OK);}
}

回调参数封装

package com.ruoyi.coupon.payment.event;import org.springframework.context.ApplicationEvent;
import org.springframework.core.annotation.Order;import java.util.Map;/*** 商城支付项的支付成功和退款成功事件*/
@Order(500)
public class PaymentEvent extends ApplicationEvent {private static final long serialVersionUID = 1L;private final String orderId;private final Integer type;//0:支付成功 1:退款成功private final Map passbackParams; //回传参数private final String actionMoney; //支付或退款金额public PaymentEvent(Object source, String orderId, Integer type, Map passbackParams,String actionMoney) {super(source);this.orderId=orderId;this.type=type;this.passbackParams=passbackParams;this.actionMoney=actionMoney;}public String getOrderId() {return this.orderId;}public Integer getType() {return this.type;}public Map getPassbackParams() {return this.passbackParams;}public String getActionMoney() {return this.actionMoney;}
}

uniapp端获取公众号code

//获取codeuni.navigateTo({url:"/pages/WeChatOfficialAccounts/getCode"})
<template><view>获取信息中...</view>
</template><script>export default {data() {return {code:''}},onLoad(){let appid = 'wx29d501';let redirect_uri='http://qy.gsjf.cc/h5/#/pages/WeChatOfficialAccounts/getCode'redirect_uri  = encodeURIComponent(redirect_uri)//console.log('redirect_uri', redirect_uri);let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect`;this.code = this.getUrlCode().code;if (this.code == null || this.code === '' ) {//window.location.href = url;}else{//获取到code后的逻辑console.log('code', this.code);/*let pages = getCurrentPages(); // 当前页页⾯实例console.log('pages',pages);//let nowPage = pages[pages.length -1]; //当前页⾯实例let prevPage = pages[pages.length -2]; // 上一页面实例let object ={code: this.code};prevPage.$vm.getCodeBack(object);*//* uni.navigateBack({  //uni.navigateTo跳转的返回,默认1为返回上一级delta: 2}); */localStorage.setItem('weChatOfficialAccountsCode', this.code);window.history.go(-2);}},methods: {getUrlCode() { // 截取url中的code方法var url = location.searchvar theRequest = new Object()if (url.indexOf("?") != -1) {var str = url.substr(1)var strs = str.split("&");for (var i = 0; i < strs.length; i++) {theRequest[strs[i].split("=")[0]] = (strs[i].split("=")[1])}}// console.log(theRequest)console.log(theRequest)return theRequest},}}
</script><style></style>

获取code后,返回跳转前页面,在跳转前页面获取code

onLoad() {const data = localStorage.getItem('weChatOfficialAccountsCode');if(data != null){this.getCodeBack(data);}else{//获取codeuni.navigateTo({url:"/pages/WeChatOfficialAccounts/getCode"})}},onShow(){const data = localStorage.getItem('weChatOfficialAccountsCode');if(data != null){this.getCodeBack(data);}else{//获取codeuni.navigateTo({url:"/pages/WeChatOfficialAccounts/getCode"})}},onUnload(){localStorage.removeItem('weChatOfficialAccountsCode');this.weChatOfficialAccountsCode=null;},

前端调起支付接口

npm install jweixin-module
localStorage.removeItem('weChatOfficialAccountsCode');this.weChatOfficialAccountsCode=null;let dataV=JSON.parse(res.data.payStrand)jweixin.config({debug: false,appId: dataV.appId,timestamp: dataV.timeStamp,nonceStr: dataV.nonceStr,signature: dataV.signature,jsApiList: ['chooseWXPay']});jweixin.ready(function() {jweixin.chooseWXPay({timestamp: dataV.timeStamp,nonceStr: dataV.nonceStr,package: dataV.package,signType: dataV.signType,paySign: dataV.paySign,success: function() {uni.showToast({title: '支付成功',icon: 'none'});},cancel: function(res) {uni.showToast({title: '支付失败',icon: 'none'});},complete: function() {}});});

相关文章:

spring boot + uniapp 微信公众号 jsapi 支付

后端支付类 package com.ruoyi.coupon.payment;import com.google.gson.Gson; import com.ruoyi.coupon.payment.dto.PayParamJsapiDto; import com.ruoyi.coupon.payment.dto.RefundParam; import com.ruoyi.coupon.service.ICouponConfigService; import com.wechat.pay.jav…...

【数学建模】《实战数学建模:例题与讲解》第九讲-时间序列分析(含Matlab代码)

【数学建模】《实战数学建模&#xff1a;例题与讲解》第九讲-时间序列分析&#xff08;含Matlab代码&#xff09; 基本概念确定性时间序列分析方法平稳时间序列模型ARIMA模型季节性序列 习题8.11. 题目要求2.解题过程3.程序4.结果 习题8.21. 题目要求2.解题过程3.程序4.结果 习…...

大话数据结构-查找-有序表查找

注&#xff1a;本文同步发布于稀土掘金。 3 有序表查找 3.1 折半查找 折半查找&#xff08;Binary Search&#xff09;技术&#xff0c;又称为二分查找&#xff0c;它的前提是线性表中的记录必须是关键码有序&#xff08;通常从小到大有序&#xff09;&#xff0c;线性表必须…...

Qt实现二维码生成和识别

一、简介 QZxing开源库: 生成和识别条码和二维码 下载地址&#xff1a;https://gitcode.com/mirrors/ftylitak/qzxing/tree/master 二、编译与使用 1.下载并解压&#xff0c;解压之后如图所示 2.编译 打开src目录下的QZXing.pro&#xff0c;选择合适的编译器进行编译 最后生…...

MyBatisX插件

MyBatisX插件 MyBatis-Plus为我们提供了强大的mapper和service模板&#xff0c;能够大大的提高开发效率。 但是在真正开发过程中&#xff0c;MyBatis-Plus并不能为我们解决所有问题&#xff0c;例如一些复杂的SQL&#xff0c;多表联查&#xff0c;我们就需要自己去编写代码和SQ…...

《C++20设计模式》学习笔记---原型模式

C20设计模式 第 4 章 原型模式4.1 对象构建4.2 普通拷贝4.3 通过拷贝构造函数进行拷贝4.4 “虚”构造函数4.5 序列化4.6 原型工厂4.7 总结4.8 代码 第 4 章 原型模式 考虑一下我们日常使用的东西&#xff0c;比如汽车或手机。它们并不是从零开始设计的&#xff0c;相反&#x…...

SpringBootAdmin设置邮件通知

如果你想要在Spring Boot Admin中配置邮件通知&#xff0c;可以按照以下步骤进行操作&#xff1a; 添加邮件通知的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dep…...

深度解析IP应用场景API:提升风险控制与反欺诈能力

前言 在当今数字化时代&#xff0c;网络安全和用户数据保护成为企业日益关注的焦点。IP应用场景API作为一种强大的工具&#xff0c;不仅能够在线调用接口获取IP场景属性&#xff0c;而且具备识别IP真人度的能力&#xff0c;为企业提供了卓越的风险控制和反欺诈业务能力。本文将…...

Java连接数据库增删改查-MyBatis

准备工作&#xff1a; 1.创建一个springboot项目&#xff0c;并添加四个依赖 分别是&#xff0c;MyBatis的启动依赖和安装依赖&#xff0c;SQL的依赖&#xff0c;测试依赖&#xff0c;如下&#xff1a; 2.然后创建一张至少两条数据的表 &#xff08;表可以用各种图形化工具创…...

在国内,现在月薪1万是什么水平?

看到网友发帖问&#xff1a;现在月薪1W是什么水平&#xff1f; 在现如今的情况下&#xff0c;似乎月薪过万这个标准已经成为衡量个人能力的一个标准了&#xff0c;尤其是现在互联网横行的时代&#xff0c;好像年入百万&#xff0c;年入千万就应该是属于大众的平均水平。 我不是…...

【Python网络爬虫入门教程1】成为“Spider Man”的第一课:HTML、Request库、Beautiful Soup库

Python 网络爬虫入门&#xff1a;Spider man的第一课 写在最前面背景知识介绍蛛丝发射器——Request库智能眼镜——Beautiful Soup库 第一课总结 写在最前面 有位粉丝希望学习网络爬虫的实战技巧&#xff0c;想尝试搭建自己的爬虫环境&#xff0c;从网上抓取数据。 前面有写一…...

燕千云汇联易联袂出击:护航医企合规,丝滑内外协作

&#x1f449; 如想详细了解燕千云医药行业快速实施包&#xff08;ITFA&#xff09;&#xff0c;可继续阅读详细内容&#xff1a; 文/玉娇龙 一. 医药行业数字化挑战 医药研发从基础研究到最终注册上市的整个生命周期长则需要10多年&#xff0c;短则需要6-7年&#xff0c;在漫长…...

【线性代数与矩阵论】Jordan型矩阵

Jordan型矩阵 2023年11月3日 #algebra 文章目录 Jordan型矩阵1. 代数重数与几何重数2. Jordan块与Jordan标准型2.1 最小多项式与Jordan标准型2.2 两类重要矩阵 3. 矩阵的Jordan分解3.1 Jordan分解的应用 下链 1. 代数重数与几何重数 在对向量做线性变换时&#xff0c;向量空间…...

laravel的ORM 对象关系映射

Laravel 中的 ORM&#xff08;Eloquent ORM&#xff09;是 Laravel 框架内置的一种对象关系映射系统&#xff0c;用于在 PHP 应用中与数据库进行交互。Eloquent 提供了一种优雅而直观的语法&#xff0c;使得开发者可以使用面向对象的方式进行数据库查询和操作。 定义模型&…...

049:VUE 引入jquery的方法和配置

第049个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…...

Qt设置类似于qq登录页面

头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QWindow> #include <QIcon> #include <QLabel> #include <QMovie> #include <QLineEdit> #include <QPushButton>QT_BEGIN_NAMESPACE namespace Ui { class…...

【GDB】

GDB 1. GDB调试器1.1 前言1.2 GDB编译程序1.3 启动GDB1.4 载入被调试程序1.5 查看源码1.6 运行程序1.7 断点设置1.7.1 通过行号设置断点1.7.2 通过函数名设置断点1.7.3 通过条件设置断点1.7.4 查看断点信息1.7.5 删除断点 1.8 单步调试1.9 2. GDB调试core文件2.1 设定core文件的…...

深入了解Java Duration类,对时间的精细操作

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概6000多字&#xff0c;预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&#x…...

Python:核心知识点整理大全5-笔记

目录 2. 使用方法pop()删除元素 3. 弹出列表中任何位置处的元素 4. 根据值删除元素 3 章 列表简介 3.3 组织列表 3.3.1 使用方法 sort()对列表进行永久性排序 3.3.2 使用函数 sorted()对列表进行临时排序 3.3.3 倒着打印列表 3.3.4 确定列表的长度 3.5 小结 2. 使用方…...

预训练(pre-learning)、微调(fine-tuning)、迁移学习(transfer learning)

预训练&#xff08;pre-learning&#xff09; 搭建一个网络模型来完成一个特定的图像分类的任务。首先&#xff0c;你需要随机初始化参数&#xff0c;然后开始训练网络&#xff0c;不断调整参数&#xff0c;直到网络的损失越来越小。在训练的过程中&#xff0c;一开始初始化的…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...