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

Flask 前后端分离架构实现支付宝电脑网站支付功能

目录

  • Flask 前后端分离架构实现支付宝电脑网站支付功能
    • 概述
    • 1. 支付宝支付原理与流程
      • 1.1 核心概念理解
      • 1.2 支付交互流程
    • 2. 环境准备与配置
      • 2.1 项目结构与依赖
      • 2.2 密钥生成与配置
    • 3. 后端实现 (Flask API)
      • 3.1 封装支付宝SDK工具类
      • 3.2 核心路由实现
    • 4. 前端实现 (Jinja2模板与JavaScript)
      • 4.1 下单页面 (index.html)
      • 4.2 支付成功展示页 (success.html)
      • 4.3 支付失败页 (failed.html)
      • 4.4 支付跳转页 (payment.html - 可选)
    • 5. 测试与部署
      • 5.1 本地测试(沙箱环境)
      • 5.2 生产环境部署
    • 6. 常见问题排查 (FAQ)
    • 结论

Flask 前后端分离架构实现支付宝电脑网站支付功能

概述

在当今的电子商务和在线服务领域,集成安全可靠的支付功能是至关重要的。支付宝作为中国领先的第三方支付平台,提供了丰富的API接口供开发者使用。本文将详细讲解如何基于Flask框架,采用前后端分离的架构,实现支付宝电脑网站支付功能的完整集成。我们将从原理分析、环境搭建、密钥配置,到前端页面构建、后端接口实现,最后进行联调测试,提供一个完整的、可操作的解决方案。本文假设您已具备基本的Python和Web开发知识。

1. 支付宝支付原理与流程

1.1 核心概念理解

在开始编码之前,必须理解支付宝交互中的几个核心概念:

  • 应用ID (app_id):在支付宝开放平台创建应用后获得,是应用的唯一标识。
  • 商户订单号 (out_trade_no):由商户网站自行生成的唯一订单号,用于标识一次交易请求。
  • 加签与验签:为了保证交易请求在传输过程中不被篡改,商户需要使用应用私钥对请求参数进行签名(加签),支付宝服务器使用支付宝公钥来验证这个签名是否有效(验签)。同理,支付宝发送的异步通知也会包含签名,商户需要用支付宝公钥进行验证。推荐使用 RSA2 算法。
  • 异步通知 (notify_url):支付成功后,支付宝服务器会主动向商户配置的后端接口(一个URL)发送POST请求,通知支付结果。这是确定交易最终状态最可靠的方式,所有核心业务逻辑(如更新订单状态、发放商品)都应在此处完成。
  • 同步通知 (return_url):支付完成后,支付宝会引导用户的浏览器跳转回商户网站的一个页面。注意:这个跳转可能因用户关闭页面等原因而不发生,因此只能用于结果展示,不能作为支付成功的依据。

1.2 支付交互流程

整个支付的交互过程涉及用户、商户前端、商户后端和支付宝服务器四方,其序列图如下:

用户浏览器商户前端(Flask模板/Javascript)商户后端(Flask API)支付宝服务器1. 提交订单2. POST /create_payment (订单信息)3. 生成订单号,构造请求4. 参数排序、签名(Sign)5. 返回支付页URL & 订单号6. 引导跳转或生成表单自动提交7. 重定向到支付宝支付页面8. 在支付宝页面完成支付9. 异步POST通知(notify_url)10. 验证签名、处理业务逻辑11. 返回'success'12. 引导跳转回return_url13. GET 访问return_url14. 返回支付结果展示页面15. (可选) 前端主动查询订单状态16. GET /query_order?out_trade_no=...17. 返回订单状态用户浏览器商户前端(Flask模板/Javascript)商户后端(Flask API)支付宝服务器

2. 环境准备与配置

2.1 项目结构与依赖

创建项目文件夹,结构如下:

flask_alipay_project/
├── app.py                 # Flask应用主入口
├── alipay_utils.py        # 支付宝SDK封装工具类
├── requirements.txt       # 项目依赖
├── keys/                  # 存放密钥的目录(务必加入.gitignore)
│   ├── app_private_key.pem
│   └── alipay_public_key.pem
└── templates/             # Jinja2模板目录├── index.html         # 下单页面├── payment.html       # 支付跳转页├── success.html       # 支付成功展示页└── failed.html        # 支付失败展示页

安装必要的Python库:

# requirements.txt
Flask==2.3.3
python-alipay-sdk==3.3.0

执行:

pip install -r requirements.txt

2.2 密钥生成与配置

  1. 生成商户密钥对

    # 生成PKCS8格式的私钥(2048位)
    openssl genrsa -out app_private_key.pem 2048
    # 从私钥生成公钥
    openssl rsa -in app_private_key.pem -pubout -out app_public_key.pem
    
  2. 支付宝平台配置

    • 登录支付宝开放平台。
    • 创建应用(例如“电脑网站支付”应用),获取APPID
    • 在“接口加签方式”中,设置“公钥”。将刚生成的app_public_key.pem文件内容(去除-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----,合并为一行)粘贴进去。
    • 保存后,平台会生成一个“支付宝公钥”,请将其下载保存为alipay_public_key.pem

重要安全提示keys/文件夹必须添加到.gitignore中,严禁将私钥提交到代码仓库。

3. 后端实现 (Flask API)

3.1 封装支付宝SDK工具类

首先创建一个工具类,统一初始化AliPay对象。

# alipay_utils.pyfrom alipay import AliPay
from alipay.utils import AliPayConfig
import osdef get_alipay_client():"""创建并返回一个配置好的AliPay实例。用于生产环境,如需沙箱环境,将debug=True并更换网关。Returns:AliPay: 初始化好的AliPay客户端对象。"""# 应用IDapp_id = "202100xxxxxxxxxx"  # 替换为你的APPID# 获取当前文件所在目录的绝对路径,并构建密钥文件路径current_dir = os.path.dirname(os.path.abspath(__file__))key_dir = os.path.join(current_dir, 'keys')# 读取应用私钥app_private_key_path = os.path.join(key_dir, 'app_private_key.pem')with open(app_private_key_path, 'r', encoding='utf-8') as f:app_private_key_string = f.read()# 读取支付宝公钥alipay_public_key_path = os.path.join(key_dir, 'alipay_public_key.pem')with open(alipay_public_key_path, 'r', encoding='utf-8') as f:alipay_public_key_string = f.read()# 创建并返回AliPay实例alipay_client = AliPay(appid=app_id,app_private_key_string=app_private_key_string,alipay_public_key_string=alipay_public_key_string,sign_type="RSA2",  # 推荐使用RSA2debug=False,  # 此处为False,指向生产环境。沙箱环境请改为Trueverbose=False,  # 是否输出调试信息config=AliPayConfig(timeout=15,  # 请求超时时间(秒)ciphers=None  # 可设置SSL加密套件))return alipay_client

3.2 核心路由实现

接下来在app.py中实现主要的业务路由。

# app.pyfrom flask import Flask, request, jsonify, render_template, redirect
from alipay_utils import get_alipay_client
import timeapp = Flask(__name__)
app.config['JSON_AS_ASCII'] = False  # 确保中文正常显示# 模拟的订单存储,实际项目中应使用数据库
# 格式: { out_trade_no: { 'subject': ..., 'amount': ..., 'status': ... } }
orders = {}@app.route('/')
def index():"""首页,展示下单页面"""return render_template('index.html')@app.route('/api/create_payment', methods=['POST'])
def create_payment():"""创建支付订单接口 (API)接收前端传来的订单信息,调用支付宝接口生成支付URL。Expected JSON: {"subject": "商品标题", "total_amount": "0.01"}"""try:# 1. 获取前端传入的参数data = request.get_json()if not data:return jsonify({'code': 400, 'msg': '无效的请求数据'}), 400subject = data.get('subject')total_amount = str(data.get('total_amount'))  # 确保是字符串if not subject or not total_amount:return jsonify({'code': 400, 'msg': '参数subject和total_amount不能为空'}), 400# 2. 生成商户订单号(必须唯一)out_trade_no = "T" + str(int(time.time() * 1000))# 3. 初始化支付宝客户端alipay_client = get_alipay_client()# 4. 调用SDK,生成支付请求参数order_string = alipay_client.api_alipay_trade_page_pay(out_trade_no=out_trade_no,          # 商户订单号total_amount=total_amount,          # 订单金额(单位:元,字符串)subject=subject,                    # 订单标题return_url=request.host_url + "payment/return",  # 同步通知URLnotify_url=request.host_url + "payment/notify",  # 异步通知URL(需公网能访问)# 更多可选参数,如商品详情`body`、超时时间`time_expire`等# product_code="FAST_INSTANT_TRADE_PAY"  # 销售产品码,电脑网站支付固定值)# 5. 拼接支付页面URL# 生产环境网关gateway = "https://openapi.alipay.com/gateway.do?"# 如果是沙箱环境,使用以下网关,并确保get_alipay_client中debug=True# gateway = "https://openapi.alipaydev.com/gateway.do?"pay_url = gateway + order_string# 6. (模拟)保存订单信息orders[out_trade_no] = {'subject': subject,'total_amount': total_amount,'status': '待支付'  # 初始状态}# 7. 返回支付URL和订单号给前端return jsonify({'code': 200,'msg': 'success','data': {'pay_url': pay_url,'out_trade_no': out_trade_no}})except Exception as e:app.logger.error(f"创建支付订单时发生错误: {e}")return jsonify({'code': 500, 'msg': '服务器内部错误'}), 500@app.route('/payment/notify', methods=['POST'])
def payment_notify():"""支付宝异步通知接口 (API)支付宝服务器会在用户支付成功后主动POST消息到此接口。这是处理业务逻辑(如更新订单状态)的核心。"""# 1. 获取POST参数并转换为字典data = request.form.to_dict()app.logger.info(f"接收到支付宝异步通知: {data}")# 2. 获取签名并从参数字典中移除(sign和sign_type不参与签名验证)signature = data.pop('sign', None)sign_type = data.pop('sign_type', None)  # 通常是RSA2# 3. 初始化支付宝客户端并验证签名alipay_client = get_alipay_client()success = alipay_client.verify(data, signature)if success:# 4. 签名验证通过trade_status = data.get('trade_status')out_trade_no = data.get('out_trade_no')total_amount = data.get('total_amount')trade_no = data.get('trade_no')  # 支付宝交易号app.logger.info(f"签名验证成功。订单: {out_trade_no}, 状态: {trade_status}")if trade_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'):# 5. 支付成功,处理业务逻辑# TODO: 这里应访问数据库,更新订单状态为“已支付”# 重要:需要检查该订单是否已经处理过(幂等性),以及金额是否匹配if out_trade_no in orders:orders[out_trade_no]['status'] = '已支付'orders[out_trade_no]['alipay_trade_no'] = trade_noapp.logger.info(f"订单 {out_trade_no} 状态更新为已支付。")# 6. 处理成功后,必须返回 'success'(不带引号)字符串# 否则支付宝会认为通知失败,在一定策略下重复发送通知return 'success'else:# 其他状态,如 TRADE_CLOSED(交易关闭)app.logger.warning(f"订单 {out_trade_no} 支付未成功,状态为: {trade_status}")# 仍然返回'success',告知支付宝已收到通知,但业务上不更新订单为成功return 'success'else:# 7. 签名验证失败,记录日志并返回'failure'app.logger.error("支付宝异步通知签名验证失败!潜在的安全风险!")return 'failure'@app.route('/payment/return', methods=['GET'])
def payment_return():"""支付同步跳转返回页面用户支付完成后,支付宝会引导用户跳转回此页面。注意:此页面不可靠,仅用于展示结果,不能作为支付成功的依据。"""# 1. 获取URL参数data = request.args.to_dict()app.logger.info(f"接收到支付宝同步返回: {data}")# 2. 获取并移除签名signature = data.pop('sign', None)sign_type = data.pop('sign_type', None)# 3. 验证签名alipay_client = get_alipay_client()success = alipay_client.verify(data, signature)if success:out_trade_no = data.get('out_trade_no')# 4. 验证通过,通常渲染一个“支付成功”的页面,并提示用户“等待服务器确认”# 为了更好的用户体验,可以在这里主动查询一次订单状态(见下方/query_order接口)return render_template('success.html', out_trade_no=out_trade_no, data=data)else:# 5. 验证失败return render_template('failed.html', message="返回参数验证失败")@app.route('/api/query_order', methods=['GET'])
def query_order():"""查询订单状态接口 (API)供前端在同步返回页面或用户主动查询时调用,以确认订单最终状态。"""out_trade_no = request.args.get('out_trade_no')if not out_trade_no:return jsonify({'code': 400, 'msg': '缺少参数out_trade_no'}), 400# 1. 先检查本地订单状态(模拟数据库查询)local_order = orders.get(out_trade_no, {})local_status = local_order.get('status', '订单不存在')# 2. 如果本地状态已是“已支付”,则直接返回if local_status == '已支付':return jsonify({'code': 200,'msg': 'success','data': {'out_trade_no': out_trade_no,'status': 'paid',  # 统一状态标识'msg': '支付成功','source': 'local_db'}})# 3. 如果本地未支付,则主动向支付宝查询订单状态try:alipay_client = get_alipay_client()result = alipay_client.api_alipay_trade_query(out_trade_no=out_trade_no)if result.get('code') == '10000':  # 接口调用成功trade_status = result.get('trade_status')total_amount = result.get('total_amount')if trade_status in ('TRADE_SUCCESS', 'TRADE_FINISHED'):# 查询结果显示支付成功,更新本地订单状态# TODO: 更新数据库if out_trade_no in orders:orders[out_trade_no]['status'] = '已支付'orders[out_trade_no]['alipay_trade_no'] = result.get('trade_no')return jsonify({'code': 200,'msg': 'success','data': {'out_trade_no': out_trade_no,'status': 'paid','msg': '支付成功','source': 'alipay_query'}})elif trade_status == 'WAIT_BUYER_PAY':return jsonify({'code': 200,'msg': 'success','data': {'out_trade_no': out_trade_no,'status': 'waiting','msg': '等待用户付款','source': 'alipay_query'}})else:# 其他状态,如TRADE_CLOSEDreturn jsonify({'code': 200,'msg': 'success','data': {'out_trade_no': out_trade_no,'status': 'failed','msg': f'交易未成功: {trade_status}','source': 'alipay_query'}})else:# 支付宝查询接口返回错误sub_code = result.get('sub_code')sub_msg = result.get('sub_msg')return jsonify({'code': 500,'msg': f'支付宝查询失败: {sub_code} - {sub_msg}'}), 500except Exception as e:app.logger.error(f"查询订单 {out_trade_no} 时发生异常: {e}")return jsonify({'code': 500, 'msg': '查询订单状态失败'}), 500if __name__ == '__main__':app.run(debug=True, host='0.0.0.0', port=5000)

4. 前端实现 (Jinja2模板与JavaScript)

4.1 下单页面 (index.html)

<!DOCTYPE html>
<!-- templates/index.html -->
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Flask支付宝支付演示</title><style>body { font-family: sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }.form-group { margin-bottom: 15px; }label { display: block; margin-bottom: 5px; }input { width: 100%; padding: 8px; box-sizing: border-box; }button { background-color: #1677FF; color: white; padding: 10px 15px; border: none; cursor: pointer; }#result { margin-top: 20px; padding: 10px; border: 1px solid #ddd; }</style>
</head>
<body><h1>生成支付订单</h1><form id="paymentForm"><div class="form-group"><label for="subject">商品名称 (subject):</label><input type="text" id="subject" name="subject" value="测试商品" required></div><div class="form-group"><label for="total_amount">支付金额 (元) (total_amount):</label><input type="number" id="total_amount" name="total_amount" value="0.01" min="0.01" step="0.01" required></div><button type="submit">生成支付链接</button></form><div id="result" style="display: none;"><p>订单号: <span id="outTradeNo"></span></p><p>支付URL已生成,点击按钮跳转到支付宝完成支付。</p><!-- 方式一:直接显示链接 --><!-- <p><a id="payLink" href="#" target="_blank">点击去支付</a></p> --><!-- 方式二:自动提交表单(更常用) --><form id="alipayForm" action="" method="GET" style="display: none;"><!-- 参数已包含在URL中,无需额外字段 --></form><button onclick="document.getElementById('alipayForm').submit();">跳转到支付宝支付</button></div><script>document.getElementById('paymentForm').addEventListener('submit', async function(e) {e.preventDefault();const formData = {subject: document.getElementById('subject').value,total_amount: document.getElementById('total_amount').value};try {const response = await fetch('/api/create_payment', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify(formData)});const result = await response.json();if (result.code === 200) {const data = result.data;document.getElementById('outTradeNo').textContent = data.out_trade_no;// 设置表单的Action为支付URLdocument.getElementById('alipayForm').action = data.pay_url;document.getElementById('result').style.display = 'block';// 如果想自动跳转,可以取消下一行的注释// document.getElementById('alipayForm').submit();} else {alert('生成支付链接失败: ' + result.msg);}} catch (error) {console.error('Error:', error);alert('请求失败,请检查网络或控制台。');}});</script>
</body>
</html>

4.2 支付成功展示页 (success.html)

<!DOCTYPE html>
<!-- templates/success.html -->
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>支付成功 - 等待确认</title><script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
<body><h1>支付完成!</h1><p>订单号: {{ out_trade_no }}</p><p>正在向服务器确认支付结果,请稍候...</p><p>如果页面长时间无响应,<a href="/">点此返回首页</a></p><script>// 页面加载后,主动查询订单状态const outTradeNo = "{{ out_trade_no }}";function queryOrderStatus() {fetch(`/api/query_order?out_trade_no=${outTradeNo}`).then(response => response.json()).then(result => {if (result.code === 200) {const data = result.data;if (data.status === 'paid') {Swal.fire({icon: 'success',title: '支付成功!',text: `订单 ${outTradeNo} 已支付成功。`,confirmButtonText: '好的'}).then(() => {// 可跳转到订单详情页等window.location.href = "/";});} else if (data.status === 'waiting') {Swal.fire({icon: 'info',title: '等待付款',text: '您尚未完成支付,请在支付宝App内完成付款。',confirmButtonText: '知道了'});} else {Swal.fire({icon: 'error',title: '支付未成功',text: `订单状态: ${data.msg}`,confirmButtonText: '知道了'});}} else {Swal.fire({icon: 'error',title: '查询失败',text: result.msg,confirmButtonText: '知道了'});}}).catch(error => {console.error('查询错误:', error);Swal.fire({icon: 'error',title: '网络错误',text: '查询订单状态时发生网络错误,请稍后刷新页面重试。',confirmButtonText: '知道了'});});}// 页面加载后延迟一秒查询,给后端处理异步通知留点时间setTimeout(queryOrderStatus, 1000);</script>
</body>
</html>

4.3 支付失败页 (failed.html)

<!DOCTYPE html>
<!-- templates/failed.html -->
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>支付失败或异常</title>
</head>
<body><h1>支付过程发生异常</h1><p>原因: {{ message }}</p><p>请返回<a href="/">首页</a>重新尝试,或联系客服。</p>
</body>
</html>

4.4 支付跳转页 (payment.html - 可选)

如果不想在前端直接提交表单,可以创建一个中间页来处理跳转。

<!DOCTYPE html>
<!-- templates/payment.html -->
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>正在跳转到支付宝...</title>
</head>
<body><h1>正在跳转到支付宝支付页面</h1><p>如果跳转失败,<a id="payLink" href="#">请点击这里</a></p><script>// 从URL中获取支付URLconst urlParams = new URLSearchParams(window.location.search);const payUrl = urlParams.get('pay_url');if (payUrl) {document.getElementById('payLink').href = payUrl;// 自动跳转window.location.href = payUrl;} else {document.body.innerHTML = '<h1>错误:缺少支付参数</h1>';}</script>
</body>
</html>

5. 测试与部署

5.1 本地测试(沙箱环境)

  1. 修改配置:在alipay_utils.py中,将debug=True,并使用沙箱环境的APPID和对应的密钥。
  2. 启动应用:运行python app.py
  3. 访问:打开http://127.0.0.1:5000
  4. 支付测试:使用支付宝提供的沙箱钱包App(需单独下载)扫描二维码进行支付测试。使用沙箱买家账号付款。

5.2 生产环境部署

  1. 配置:确保debug=False,并使用生产环境的APPID和密钥。
  2. HTTPS:生产环境的notify_urlreturn_url必须支持HTTPS。可以使用Nginx反向代理Flask应用并配置SSL证书。
  3. WSGI服务器:不要使用Flask自带的开发服务器。使用Gunicorn或uWSGI等生产级WSGI服务器。
    pip install gunicorn
    gunicorn -w 4 -b 0.0.0.0:5000 app:app
    
  4. 网络:确保您的服务器IP地址没有被防火墙屏蔽,支付宝服务器能够访问到您的/payment/notify接口。

6. 常见问题排查 (FAQ)

Q1: 签名错误 (sign check failed: check Sign and Data Fail)?
A1: 这是最常见的问题。请按以下步骤排查:

  • 密钥匹配:确认开放平台设置的是你的公钥,代码里读取的是你的私钥和支付宝给的公钥
  • 密钥格式:确保密钥文件是正确的PEM格式,没有多余空格或换行。python-alipay-sdk需要PKCS8格式的私钥。
  • 参数编码:确保所有字符串参数为UTF-8编码。

Q2: 收不到异步通知 (notify_url)?
A2:

  • 公网可达:确保你的notify_url是公网HTTPS地址,并能被支付宝服务器访问。
  • 及时响应:你的接口必须在处理完成后返回纯文本success(不能有多余字符或JSON),否则支付宝会认为通知失败并重试。
  • 日志排查:仔细查看Flask应用的日志,确认是否有POST请求到来。

Q3: 如何处理重复的异步通知?
A3: 在处理通知的业务逻辑中,必须实现幂等性。即在更新订单状态前,先检查数据库中该订单是否已经是“已支付”状态,如果是,则直接返回success,不再执行后续更新和发货逻辑。

Q4: 沙箱测试一切正常,上线生产后失败?
A4:

  • 检查debug标志是否已设为False
  • 检查生产环境的密钥和APPID是否正确配置。
  • 确保生产环境的域名已在支付宝开放平台的应用设置中配置好。

结论

本文详细介绍了如何使用Flask框架前后端分离地实现支付宝电脑网站支付功能。核心要点包括:

  1. 理解流程:深刻理解同步通知和异步通知的区别与用途。
  2. 安全第一:妥善保管私钥,严格进行签名验证。
  3. 依赖SDK:使用python-alipay-sdk极大简化了签名和API调用的复杂度。
  4. 幂等性:异步通知处理必须具备幂等性,以防止重复业务操作。
  5. 主动查询:在同步返回页面,结合主动查询接口来向用户展示最终状态,提供更好的用户体验。

此方案提供了一个健壮的生产环境支付集成基础,您可以根据实际业务需求,将其与用户系统、订单数据库、日志监控等模块进行对接。希望本指南能帮助您顺利完成支付功能的开发。


文章转载自:

http://QRKoSJzr.dcccL.cn
http://FBAMwy7v.dcccL.cn
http://UWy7GRdv.dcccL.cn
http://PiypzB2b.dcccL.cn
http://2aeSbG5x.dcccL.cn
http://FghSEG4S.dcccL.cn
http://HjnmLpMJ.dcccL.cn
http://r4JbehLv.dcccL.cn
http://bdqYyEVa.dcccL.cn
http://3w96EW1j.dcccL.cn
http://EyJtXFEm.dcccL.cn
http://FZLpP9OF.dcccL.cn
http://rR9KKWCx.dcccL.cn
http://E33b6BJE.dcccL.cn
http://J5XkJmCt.dcccL.cn
http://Zu1EbIPq.dcccL.cn
http://sJLSYHGc.dcccL.cn
http://NS0VQjwA.dcccL.cn
http://oXJcribS.dcccL.cn
http://c1255XUI.dcccL.cn
http://oe4qH9Ap.dcccL.cn
http://ElvLEkoR.dcccL.cn
http://9Rnkv6td.dcccL.cn
http://OknDHO1D.dcccL.cn
http://572F0VQH.dcccL.cn
http://OLRVGknu.dcccL.cn
http://d6cskqC2.dcccL.cn
http://CC1sMYAU.dcccL.cn
http://t7Yky29i.dcccL.cn
http://CKFRvzJE.dcccL.cn
http://www.dtcms.com/a/376968.html

相关文章:

  • Next.js 客户端渲染 (CSR) 与 Next.js 的结合使用
  • GitHub 镜像站点
  • S7-200 SMART 实战:自动包装控制系统的指令应用拆解(程序部分)
  • 从音频到Token:构建原神角色语音识别模型的完整实践
  • 【从0开始学习Java | 第16篇】数据结构 -树
  • (设计模式)区分建造者、 规格模式(MyBatis Example+Criteria )
  • Shell 条件测试与 if 语句:从基础到实战
  • 数据结构 之 【布隆过滤器 的简介】
  • 《sklearn机器学习——数据预处理》归一化
  • 网络编程(7)
  • 嘉立创EDA从原理图框选住器件进行PCB布局
  • 浅谈代理流程自动化 (APA)
  • 图论3 图的遍历
  • MySQL内核革新:智能拦截全表扫描,百度智能云守护数据库性能与安全
  • 从0°到180°,STM32玩转MG996R舵机
  • Openresty Tracing 最佳实践
  • 少儿舞蹈小程序(12)作品列表查询搭建
  • 机器学习投票分类
  • Python Web工程之Flask项目中添加健康检查
  • javaEE-Spring IOCDI
  • 《常见关键字知识整理》
  • C++中的单例模式的实现
  • 淘宝闪购基于FlinkPaimon的Lakehouse生产实践:从实时数仓到湖仓一体化的演进之路
  • 云手机怎样进行自动化运行?
  • FPGA入门-状态机
  • 【Python Tkinter 】图形用户界面(GUI)开发及打包EXE指南
  • 工作效率翻倍!Excel多文件合并工具
  • 【Pywinauto库】8.4 pywinauto.timings模块
  • 4.7 静态分支, 动态分支和变体
  • LangGraph中ReAct模式的深度解析:推理与行动的完美融合——从理论到实践的智能Agent构建指南