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代码)
【数学建模】《实战数学建模:例题与讲解》第九讲-时间序列分析(含Matlab代码) 基本概念确定性时间序列分析方法平稳时间序列模型ARIMA模型季节性序列 习题8.11. 题目要求2.解题过程3.程序4.结果 习题8.21. 题目要求2.解题过程3.程序4.结果 习…...

大话数据结构-查找-有序表查找
注:本文同步发布于稀土掘金。 3 有序表查找 3.1 折半查找 折半查找(Binary Search)技术,又称为二分查找,它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须…...

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

MyBatisX插件
MyBatisX插件 MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率。 但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQ…...
《C++20设计模式》学习笔记---原型模式
C20设计模式 第 4 章 原型模式4.1 对象构建4.2 普通拷贝4.3 通过拷贝构造函数进行拷贝4.4 “虚”构造函数4.5 序列化4.6 原型工厂4.7 总结4.8 代码 第 4 章 原型模式 考虑一下我们日常使用的东西,比如汽车或手机。它们并不是从零开始设计的,相反&#x…...
SpringBootAdmin设置邮件通知
如果你想要在Spring Boot Admin中配置邮件通知,可以按照以下步骤进行操作: 添加邮件通知的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dep…...

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

Java连接数据库增删改查-MyBatis
准备工作: 1.创建一个springboot项目,并添加四个依赖 分别是,MyBatis的启动依赖和安装依赖,SQL的依赖,测试依赖,如下: 2.然后创建一张至少两条数据的表 (表可以用各种图形化工具创…...

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

【Python网络爬虫入门教程1】成为“Spider Man”的第一课:HTML、Request库、Beautiful Soup库
Python 网络爬虫入门:Spider man的第一课 写在最前面背景知识介绍蛛丝发射器——Request库智能眼镜——Beautiful Soup库 第一课总结 写在最前面 有位粉丝希望学习网络爬虫的实战技巧,想尝试搭建自己的爬虫环境,从网上抓取数据。 前面有写一…...

燕千云汇联易联袂出击:护航医企合规,丝滑内外协作
👉 如想详细了解燕千云医药行业快速实施包(ITFA),可继续阅读详细内容: 文/玉娇龙 一. 医药行业数字化挑战 医药研发从基础研究到最终注册上市的整个生命周期长则需要10多年,短则需要6-7年,在漫长…...
【线性代数与矩阵论】Jordan型矩阵
Jordan型矩阵 2023年11月3日 #algebra 文章目录 Jordan型矩阵1. 代数重数与几何重数2. Jordan块与Jordan标准型2.1 最小多项式与Jordan标准型2.2 两类重要矩阵 3. 矩阵的Jordan分解3.1 Jordan分解的应用 下链 1. 代数重数与几何重数 在对向量做线性变换时,向量空间…...

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

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

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类,对时间的精细操作
阅读建议 嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议: 本篇文章大概6000多字,预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强,是一篇质量分数较高的技术干货文章&#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)
预训练(pre-learning) 搭建一个网络模型来完成一个特定的图像分类的任务。首先,你需要随机初始化参数,然后开始训练网络,不断调整参数,直到网络的损失越来越小。在训练的过程中,一开始初始化的…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...