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

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;// verifierpublic static Verifier verifier;// httpClientpublic static CloseableHttpClient httpClient;@Overridepublic 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 {// 从证书管理器中获取verifierverifier = 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 {@Autowiredprivate 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));}}

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 {@Autowiredprivate LsOrderMapper orderMapper;@Autowiredprivate LsUserMapper lsUserMapper;@Autowiredprivate LsProductMapper lsProductMapper;@Autowiredprivate LsAppendMapper lsAppendMapper;/*** 立即下单** @param lsOrder 订单* @return 结果*/@Transactional(rollbackFor = Exception.class)@Overridepublic 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*/@Overridepublic AjaxResult payment(LsOrder lsOrder) {try {JSONObject order = new JSONObject();// 应用IDorder.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);// 微信httpClientCloseableHttpClient 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);}// 返回预支付idfinal 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"); //小程序appIdsb.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*/@Overridepublic 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);// 从证书管理器中获取verifierVerifier 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*/public boolean closePayOrder(String orderNo) {JSONObject obj = new JSONObject();// 直连商户号obj.put("mchid", WxPayUtils.mchId);// 请求地址String closeOrderUrl = ConstantUtils.CLOSE_PAY_ORDER_URL.replace("{out_trade_no}", orderNo);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"));// 微信httpClientCloseableHttpClient httpClient = WechatPayaHttpclientUtils.httpClient;try {if(httpClient == null){log.info("关闭订单失败,请重试,无法连接微信支付服务器!");}//执行请求CloseableHttpResponse response = httpClient.execute(httpPost);//状态码int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 204) {//关闭订单成功!log.info("微信关闭订单成功: {}", orderNo);}else if(statusCode == 202){//用户支付中,需要输入密码log.info("关闭微信订单--用户支付中,需要输入密码,暂时不做处理!");}else{log.info("关闭微信订单--关闭支付订单失败,出现未知原因: {}", EntityUtils.toString(response.getEntity()));}} catch (IOException e) {log.info("关闭微信订单--关闭订单失败: {}", e.getMessage());}return false;}/*** 订单查询 (定时查询订单, 修改订单状态)** @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":// 查询订单未支付 截止时间是否超时if (DateUtils.compareCurrentDateToEndDate(lsOrder.getNoPaymentCutoffTime())) {lsOrder.setStatus(0);if (orderMapper.updateLsOrder(lsOrder)>0) {// 微信关闭订单closePayOrder(lsOrder.getOrderNo());}}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.rhkb.cn/news/95070.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytest和Unittest测试框架的区别?

如何区分这两者&#xff0c;很简单unittest作为官方的测试框架&#xff0c;在测试方面更加基础&#xff0c;并且可以再次基础上进行二次开发&#xff0c;同时在用法上格式会更加复杂&#xff1b;而pytest框架作为第三方框架&#xff0c;方便的地方就在于使用更加灵活&#xff0…

Vue2中根据权限添加动态路由

Vue2中根据权限添加动态路由 大概记录一下主要代码 1.根据后端返回的路由列表生成左侧菜单&#xff08;后端返回的数据结构中用id和pid来区别包含关系&#xff09; 大概结构如下&#xff1a; 2.前端需要处理成包含children的树形结构 //动态生成菜单 export const gener…

【Leetcode】102.二叉树的层序遍历

一、题目 1、题目描述 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例1: 输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例2: 输入:root = [1] 输出:[[1]]示例3: 输入:root = [] 输出:[]…

电力应用 | Intewell操作系统新疆特变项目应用案例

近日&#xff0c;科东软件Intewell操作系统在新疆特变项目成功应用&#xff0c;该方案保障了变电站的电力设备在高电压下稳定运行&#xff0c;实现变电站的智能化控制&#xff0c;极大程度上节省了人力、物力和财力资源&#xff1b;可实时监控电力设备的异常情况&#xff0c;及…

【系统架构】系统架构设计之数据同步策略

文章目录 一、介绍1.1、分布式系统中的数据同步定义1.2、为何数据同步如此关键1.3、数据同步策略简介 二、为什么需要数据同步2.1、提高系统可用性2.2、备份与灾难恢复2.3、提高性能2.4、考虑地理位置&#xff08;如使用CDN&#xff09; 三、同步备份3.1、定义和概述3.2、工作原…

Vue3 setup新特性简单应用

去官网学习→组合式 API&#xff1a;setup() | Vue.js 运行示例&#xff1a; 代码&#xff1a;App.vue <template><div class"home"><img alt"Vue logo" src"../assets/logo.png"><!-- msg 组件传递数据 --><Hell…

小象课堂在线授课教育系统

此项目包含后端全部代码&#xff0c;前端包括后台和web界面的源码&#xff0c;数据库用的mysql,可当作课设或者毕设&#xff0c;还可写入自己的简历中 web界面展示&#xff1a; 前端后台界面展示&#xff1a; 用户管理 课程管理 内容配置 订单管理 系统管理 系统监控

部署mysql到win10电脑上

中间出现了很多问题&#xff0c; 记录一下 我这边是去官网下载的 &#xff0c;链接&#xff1a;https://dev.mysql.com/downloads/mysql/ 我这边选了不是最新版本的MySQL&#xff0c;因为第一次安装8.1.0版本的&#xff0c;死活运行不起来&#xff0c;直接卸载安重装了&#x…

【QT+ffmpeg】QT+ffmpeg 环境搭建

1.qt下载地址 download.qt.io/archive/ 2. win10sdk 下载 https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ 安装 debug工具路径 qtcreater会自动识别 调试器选择

FirmAE 工具安装(解决克隆失败 网络问题解决)

FirmAE官方推荐使用Ubuntu 18.04系统进行安装部署&#xff0c;FirmAE工具的安装部署十分简单&#xff0c;只需要拉取工具仓库后执行安装脚本即可。 首先运行git clone --recursive https://kgithub.com/pr0v3rbs/FirmAE命令 拉取FirmAE工具仓库&#xff0c;因为网络的问题&…

SSL证书过期巡检脚本

Shell版 demo.txt [rootbogon aihuidi]# cat demo.txt www.aihuidi.com:111.222.333.444 xxx.xxx.com:ip,ip脚本&#xff1a; [rootlocalhost aihuidi]# vim check_ssl.sh #!/bin/bash for line in $(cat demo.txt) dodomain$(echo ${line} | awk -F : {print $1})ip_pool$(…

前端开发工具及环境配置

1.前端开发环境node npm环境配置 第一步&#xff1a;打开Download | Node.js (nodejs.org)下载&#xff0c;解压。 找到下载压缩包进行解压 解压到D盘目录下&#xff1a; 第二步&#xff1a;配置环境变量&#xff1a;右击此电脑点击属性进入高级系统设置 点击高级系统设置进入…

Android Studio瀑布流实现

效果&#xff1a; ImageDetail class package com.example.waterfallflow; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.ImageView;public class ImageDetail extends Activity{Overrideprotected void …

【MySQL系列】表内容的基本操作(增删查改)

「前言」文章内容大致是对MySQL表内容的基本操作&#xff0c;即增删查改。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、MySQL表内容的增删查改1.1 Create1.1.1 单行数据全列插入1.1.2 多行数据指定列插入1.1.3 插入否则更新1.1.4 数据替换 1.2 Ret…

LVS - DR

LVS-DR 数据流向 客户端发送请求到 Director Server&#xff08;负载均衡器&#xff09;&#xff0c;请求的数据报文&#xff08;源 IP 是 CIP,目标 IP 是 VIP&#xff09;到达内核空间。Director Server 和 Real Server 在同一个网络中&#xff0c;数据通过二层数据链路层来传…

HackNos 3靶场

配置 进入控制面板配置网卡 第一步&#xff1a;启动靶机时按下 shift 键&#xff0c; 进入以下界面 第二步&#xff1a;选择第二个选项&#xff0c;然后按下 e 键&#xff0c;进入编辑界面 将这里的ro修改为rw single init/bin/bash&#xff0c;然后按ctrlx&#xff0c;进入…

[Go版]算法通关村第十二关黄金——字符串冲刺题

目录 题目&#xff1a;最长公共前缀解法1&#xff1a;纵向对比-循环内套循环写法复杂度&#xff1a;时间复杂度 O ( n ∗ m ) O(n*m) O(n∗m)、空间复杂度 O ( 1 ) O(1) O(1)Go代码 解法2&#xff1a;横向对比-两两对比&#xff08;类似合并K个数组、合并K个链表&#xff09;复…

【傅里叶级数与傅里叶变换】数学推导——2、[Part2:T = 2 π的周期函数的傅里叶级数展开] 及 [Part3:周期为2L的函数展开]

文章内容来自DR_CAN关于傅里叶变换的视频&#xff0c;本篇文章提供了一些基础知识点&#xff0c;比如三角函数常用的导数、三角函数换算公式等。 文章全部链接&#xff1a; 基础知识点 Part1&#xff1a;三角函数系的正交性 Part2&#xff1a;T2π的周期函数的傅里叶级数展开 P…

SASS 学习笔记 II

SASS 学习笔记 II 上篇笔记&#xff0c;SASS 学习笔记 中包含&#xff1a; 配置 变量 嵌套 这里加一个扩展&#xff0c;嵌套中有一个 & 的用法&#xff0c;使用 & 可以指代当前 block 中的 selector&#xff0c;后面可以追加其他的选择器。如当前的 scope 是 form&a…

AndroidStudio升级Gradle之坑

最近在做旧工程的升级&#xff0c;原来的Gradle版本是4.6的&#xff0c;需要升级到7.6&#xff0c;JDK从8升级到17&#xff0c;一路趟了很多坑&#xff0c;逐个记录下吧 1、Maven仓库需要升级到https 你会遇到这个报错 Using insecure protocols with repositories, without …