发起支付

接入支付宝

支付的大致流程如下图:

                                                    

部分节点详解:

沙箱环境

支付宝开发者文档

开发支付功能

cd luffy/apps
python ../../manage.py startapp payments

配置秘钥

1. 生成应用的私钥和公钥

下载对应系统的秘钥生成工具: https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1

应用公钥复制粘贴到支付宝网站页面中.

2. 保存应用私钥文件

在payments应用中新建keys目录,用来保存秘钥文件。

将应用私钥文件app_private_key.pem复制到payment/keys目录下。

-----BEGIN RSA PRIVATE KEY-----
私钥
-----END RSA PRIVATE KEY-----

3. 保存支付宝公钥

在payment/keys目录下新建alipay_public_key.pem文件,用于保存支付宝的公钥文件。

将支付宝的公钥内容复制到alipay_public_key.pem文件中

 -----BEGIN PUBLIC KEY-----
公钥
-----END PUBLIC KEY-----

4. 使用支付宝的sdk开发支付接口

SDK:https://docs.open.alipay.com/270/106291/

python版本的支付宝SDK文档:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md

安装命令:

pip install python-alipay-sdk --upgrade

流程思路:

  1.在order页面用户点击支付宝支付时,前端需要向后端发送带有订单ID值得请求,让后端通过上面安装的支付宝sdk构造链接返回来,然后再接受响应的地方跳转到支付宝提供的支付界面

<template>
.....
<el-col :span="4" class="cart-pay" ><span @click="payhandler" >支付宝支付</span></el-col>
....
</template> <script>
export default {
name:"Order", methods:{
payhandler(){
// 判断用户是否已经登陆了。
if( !this.token){
this.$router.push("/login");
} let _this = this;
// 发起请求获取购物车中的商品信息
_this.$axios.get("http://127.0.0.1:8000/pay/"+_this.order_id,{
headers: {
'Authorization': 'JWT ' + _this.token
},
responseType: 'json',
}).then(response=>{
console.log("response.data",response.data.url)
//跳转页面到支付界面
window.location.href=response.data.url; })
}
},
}
</script>

  2.后端接收到前端支付的请求,实现发起支付接口(生成支付链接返回),其中有许多配置项都需要注意,详细可参考开发者文档

class PaymentAPIView(APIView):
"""支付宝"""
permission_classes = (IsAuthenticated,) def get(self, request, order_id):
"""获取支付链接"""
# 判断订单信息是否正确
try:
order = Order.objects.get(order_id=order_id, user=request.user,
order_status=0,)
except Order.DoesNotExist:
return Response({'message': '订单信息有误'}, status=status.HTTP_400_BAD_REQUEST) # 构造支付宝支付链接地址
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"),
alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem"), # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
sign_type="RSA2", # RSA 或者 RSA2
debug=settings.ALIPAY_DEBUG
) order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order.id,
total_amount=str(order.total_price),
subject=order.order_desc,
return_url="http://127.0.0.1:8080/pay_success",
)
alipay_url = settings.ALIPAY_URL + "?" + order_string
return Response({'alipay_url': alipay_url}, status=status.HTTP_201_CREATED)

在配置文件中编辑支付宝的配置信息[实际的值根据自己的账号而定]

# 支付宝
ALIPAY_APP_ID="" # 应用ID
APLIPAY_APP_NOTIFY_URL = None # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面]
APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR,"luffy/apps/payments/keys/app_private_key.pem")
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR,"luffy/apps/payments/keys/alipay_public_key.pem")
ALIPAY_DEBUG = True
# APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do" #上线使用
APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do" #开发环境使用
ALIPAY_RETURN_URL = "http://127.0.0.1:8080/success"
ALIPAY_NOTIFY_URL = "http://127.0.0.1:8080/success"

  3.当购买人支付成功后,支付宝会跳转链接到之前我们配置好的页面中,("http://127.0.0.1:8080/success"),所以需要提前写好购买成功的界面,并在该页面向后端发送购买成功的信息,此时后端会验证更新订单状态,包括写入支付日期,以及订单状态的更改等

success.vue 前端发起请求页面:..

<template>
.....
</template> <script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default{
created(){
// 页面刷新时,最开始时候要把支付宝服务器的返回get参数结果提交给后端
// 后端需要根据这结果修改订单的状态
this.$axios.get("http://127.0.0.1:8000/pay/result"+location.search,{
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json',
}).then(response=>{
this.result = response.data
}).catch(error=>{
console.log(error.response);
})
</script>

注意,此时后端发送的数据,必须要携带支付宝在表头返回的数据,以用于后端验证

支付宝会返回的参数如下列表:(前面是域名,后面才是参数)

http://127.0.0.1:8080/success?charset=utf-8&
out_trade_no=2019040217080000000010976&
method=alipay.trade.page.pay.return&
total_amount=1206.44&
sign=XKJG5826fH%2F9%2B3jCWw2ODjlc%2FuGLfqmr5RnimSAqrh%2B5bFkWcbLDh5V6VYtMqCpwnYp3FuGPqEeUeRO6WK62Qz0Q5nQGOA394IdxPfTOzry7PXuwYf41PCbDq53yg7vCYrobz4Tt8uajeADJLJwIsL%2F%2B88vbDEISUDUujL4442kl3oLh3EDD8DxZc2LLsv1Z%2FEFGJMfcTA47A4T7qmjB%2BbLKJetZZBISdt9RDL0q8A%2BAfb8B3Ux1nq%2F0EiNGiwIlWC1pvUCHK2UXMJW3kmgU9P9Zoujrj4ER28oieQt6Rt4gQXeah5uYtAMkftWfZpiyu%2FjUkr6iRx%2B4mP5IFz4Uew%3D%3D&
trade_no=2019040222001439881000005802&
auth_app_id=2016091600523592&
version=1.0&
app_id=2016091600523592&
sign_type=RSA2&
seller_id=2088102175868026&
timestamp=2019-04-02%2017%3A13%3A15

4.后端对发送过来的请求,会进行订单是否成功的验证,若验证成功,则会修改相应的订单状态,并返回相应的订单的信息内容,以供前端渲染数据

后端代码如下:

 class PaymentAPIView(APIView):
....... class PayResultAPIView(APIView):
def get(self,request):
"""处理get返回结果的数据"""
# 接受数据
data = request.query_params.dict()
print(data)
# sign 不能参与签名验证
signature = data.pop("sign")
# print(json.dumps(data))
# print(signature)
alipay = AliPay(
appid=settings.ALIPAY_APP_ID,
app_notify_url=None, # 默认回调url
# 应用私钥
app_private_key_path=settings.APP_PRIVATE_KEY_PATH,
# 支付宝的公钥,
alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
sign_type="RSA2", # 密码加密的算法
# 开发时属于调试模式
debug = settings.ALIPAY_DEBUG # 默认False
) # verify验证支付结果,布尔值
success = alipay.verify(data, signature) if success:
# 支付成功
order = Order.objects.get(order_number=data.get("out_trade_no"))
order.order_status = 1 # 修改订单状态
order.pay_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
order.save() return Response({
"length":order.order_course.count(),
"paytime": order.pay_time,
"price":order.total_price,
"info":order.order_desc,
},status=status.HTTP_200_OK) return Response({"message":"订单没有变化"})
def post(self,request):
"""提供给支付宝发送post数据"""
# 参考上面的代码实现
# 接受数据
data = request.data.dict() # sign 不能参与签名验证
signature = data.pop("sign")
# print(json.dumps(data))
# print(signature)
alipay = AliPay(
appid=settings.ALIPAY_APP_ID,
app_notify_url=None, # 默认回调url
# 应用私钥
app_private_key_path=settings.APP_PRIVATE_KEY_PATH,
# 支付宝的公钥,
alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
sign_type="RSA2", # 密码加密的算法
# 开发时属于调试模式
debug=settings.ALIPAY_DEBUG # 默认False
) # verify验证支付结果,布尔值
success = alipay.verify(data, signature) if success:
# 支付成功
order = Order.objects.get(order_number=data.get("out_trade_no"))
order.order_status = 1 # 修改订单状态
order.pay_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
order.save() return Response({
"length": order.order_course.count(),
"paytime": order.pay_time,
"price": order.total_price,
"info": order.order_desc,
}, status=status.HTTP_200_OK) return Response({"message": "订单没有变化"})

完整代码,可详细看:

前端代码:

success.vue

<template>
<div class="success">
<Header :current_page="current_page"/>
<div class="main">
<div class="title">
<img src="../../static/images/right.svg" alt="">
<div class="success-tips">
<p class="tips1">您已成功购买 {{result.length}} 门课程!</p>
<p class="tips2">你还可以加入QQ群 <span>747556033</span> 学习交流</p>
</div>
</div>
<div class="order-info">
<p class="info1"><b>付款时间:</b><span>{{result.paytime}}</span></p>
<p class="info2"><b>付款金额:</b><span >{{result.price}}</span></p>
<p class="info3"><b>课程信息:</b><span><span>《{{result.info}}》</span></span></p>
</div>
<div class="wechat-code">
<img src="../../static/images/server.cf99f78.png" alt="" class="er">
<p><img src="../../static/images/tan.svg" alt="">重要!微信扫码关注获得学习通知&amp;课程更新提醒!否则将严重影响学习进度和课程体验!</p>
</div>
<div class="study">
<span>立即学习</span>
</div>
</div>
<Footer/>
</div>
</template> <script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default{
name:"Success",
data(){
return {
token: sessionStorage.token || localStorage.token,
current_page:0,
result:{},
};
},
components:{
Header,
Footer,
},
created(){
// 页面刷新时,最开始时候要把支付宝服务器的返回get参数结果提交给后端
// 后端需要根据这结果修改订单的状态
this.$axios.get("http://127.0.0.1:8000/pay/result"+location.search,{
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json',
}).then(response=>{
this.result = response.data
}).catch(error=>{
console.log(error.response);
})
}
}
</script> <style scoped>
.success{
padding-top: 80px;
}
.main{
height: 100%;
padding-top: 25px;
padding-bottom: 25px;
margin: 0 auto;
width: 1200px;
background: #fff;
}
.main .title{
display: flex;
-ms-flex-align: center;
align-items: center;
padding: 25px 40px;
border-bottom: 1px solid #f2f2f2;
}
.main .title .success-tips{
box-sizing: border-box;
}
.title img{
vertical-align: middle;
width: 60px;
height: 60px;
margin-right: 40px;
}
.title .success-tips{
box-sizing: border-box;
}
.title .tips1{
font-size: 22px;
color: #000;
}
.title .tips2{
font-size: 16px;
color: #4a4a4a;
letter-spacing: 0;
text-align: center;
margin-top: 10px;
}
.title .tips2 span{
color: #ec6730;
}
.order-info{
padding: 25px 48px;
padding-bottom: 15px;
border-bottom: 1px solid #f2f2f2;
}
.order-info p{
font-family: PingFangSC-Regular;
display: -ms-flexbox;
display: flex;
margin-bottom: 10px;
font-size: 16px;
}
.order-info p b{
font-weight: 400;
color: #9d9d9d;
white-space: nowrap;
}
.wechat-code{
display: flex;
-ms-flex-align: center;
align-items: center;
padding: 25px 40px;
border-bottom: 1px solid #f2f2f2;
}
.wechat-code>img{
width: 100px;
height: 100px;
margin-right: 15px;
}
.wechat-code p{
font-family: PingFangSC-Regular;
font-size: 14px;
color: #d0021b;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
}
.wechat-code p>img{
width: 16px;
height: 16px;
margin-right: 10px;
}
.study{
padding: 25px 40px;
}
.study span{
display: block;
width: 140px;
height: 42px;
text-align: center;
line-height: 42px;
cursor: pointer;
background: #ffc210;
border-radius: 6px;
font-family: PingFangSC-Regular;
font-size: 16px;
color: #fff;
}
</style>

order.vue:

<template>
<div class="cart">
<Header/>
<div class="cart-info">
<h3 class="cart-top">购物车结算 <span>共1门课程</span></h3>
<div class="cart-title">
<el-row>
<el-col :span="2">&nbsp;</el-col>
<el-col :span="10">课程</el-col>
<el-col :span="8">有效期</el-col>
<el-col :span="4">价格</el-col>
</el-row>
</div>
<div class="cart-item" v-for="item in course_list" >
<el-row>
<el-col :span="2" class="checkbox">&nbsp;&nbsp;</el-col>
<el-col :span="10" class="course-info">
<img :src="item.course.course_http_img" alt="">
<span>{{item.course.name}}</span>
</el-col>
<el-col :span="8"><span>永久有效</span></el-col>
<el-col :span="4" class="course-price">¥{{item.unit_price}}</el-col>
</el-row>
</div>
<div class="calc">
<el-row class="pay-row">
<el-col :span="4" class="pay-col"><span class="pay-text">支付方式:</span></el-col>
<el-col :span="4"><span class="alipay"><img src="../../static/images/1554167287107.png" alt=""></span></el-col>
<el-col :span="12" class="count">实付款: <span>¥{{total}}</span></el-col>
<el-col :span="4" class="cart-pay" ><span @click="payhandler" >支付宝支付</span></el-col>
</el-row>
</div>
</div>
<Footer/>
</div>
</template> <script>
import Header from "./common/Header"
import Footer from "./common/Footer" export default {
name:"Order",
data(){
return {
total:0,
course_list:[],
token: localStorage.token || sessionStorage.token,
id : localStorage.id || sessionStorage.id,
order_id:sessionStorage.order_id || null,
}
}, components:{
Header,
Footer, },
methods:{
payhandler(){
// 判断用户是否已经登陆了。
if( !this.token){
this.$router.push("/login");
} let _this = this;
// 发起请求获取购物车中的商品信息
_this.$axios.get("http://127.0.0.1:8000/pay/"+_this.order_id,{
headers: {
'Authorization': 'JWT ' + _this.token
},
responseType: 'json',
}).then(response=>{
console.log("response.data",response.data.url)
//跳转页面到支付界面
window.location.href=response.data.url; })
}
},
created() {
// 判断用户是否已经登陆了。
if( !this.token){
this.$router.push("/login");
} let _this = this;
// 发起请求获取购物车中的商品信息
_this.$axios.get("http://127.0.0.1:8000/orders/detail/"+_this.order_id,{
headers: {
'Authorization': 'JWT ' + _this.token
},
responseType: 'json',
}).then(response=>{
console.log("response.data",response.data)
_this.course_list = response.data.order_course;
_this.total = response.data.total_price })
},
}
</script> <style scoped>
.cart{
margin-top: 80px;
}
.cart-info{
overflow: hidden;
width: 1200px;
margin: auto;
}
.cart-top{
font-size: 18px;
color: #666;
margin: 25px 0;
font-weight: normal;
}
.cart-top span{
font-size: 12px;
color: #d0d0d0;
display: inline-block;
}
.cart-title{
background: #F7F7F7;
height: 70px;
}
.calc{
margin-top: 25px;
margin-bottom: 40px;
} .calc .count{
text-align: right;
margin-right: 10px;
vertical-align: middle;
}
.calc .count span{
font-size: 36px;
color: #333;
}
.calc .cart-pay{
margin-top: 5px;
width: 110px;
height: 38px;
outline: none;
border: none;
color: #fff;
line-height: 38px;
background: #ffc210;
border-radius: 4px;
font-size: 16px;
text-align: center;
cursor: pointer;
}
.cart-item{
height: 120px;
line-height: 120px;
}
.course-info img{
width: 175px;
height: 115px;
margin-right: 35px;
vertical-align: middle;
}
.alipay{
display: block;
height: 48px;
}
.alipay img{
height: 100%;
width:auto;
} .pay-text{
display: block;
text-align: right;
height: 100%;
line-height: 100%;
vertical-align: middle;
margin-top: 20px;
}
</style>

后端代码:

payment.view:

 from datetime import datetime

 from alipay import AliPay
from django.conf import settings
from django.shortcuts import render # Create your views here.
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView from luffy.apps.orders.models import Order class PaymentAPIView(APIView):
permission_classes = [IsAuthenticated] def get(self, request, pk):
"""生成支付链接的地址"""
try:
order = Order.objects.get(pk=pk)
except Order.DoesNotExist():
return Response({"message": "当前订单不存在!"}, status=status.HTTP_400_BAD_REQUEST) alipay = AliPay(
appid=settings.ALIPAY_APP_ID,
app_notify_url=None, # 默认回调url
# 应用私钥
app_private_key_path=settings.APP_PRIVATE_KEY_PATH,
# 支付宝的公钥,
alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
sign_type="RSA2", # 密码加密的算法
# 开发时属于调试模式
debug=settings.ALIPAY_DEBUG # 默认False
) # 生成参数
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no = order.order_number,
total_amount = float(order.total_price), # 订单价格,单位:元 / RMB
subject = order.order_desc, # 订单标题
return_url = settings.ALIPAY_RETURN_URL,
notify_url=settings.ALIPAY_NOTIFY_URL # 可选, 不填则使用默认notify url
)
# 生成新地址
url = settings.APIPAY_GATEWAY + "?" + order_string return Response({"url": url}, status=status.HTTP_200_OK) class PayResultAPIView(APIView):
def get(self,request):
"""处理get返回结果的数据"""
# 接受数据
data = request.query_params.dict()
# sign 不能参与签名验证
signature = data.pop("sign") alipay = AliPay(
appid=settings.ALIPAY_APP_ID,
app_notify_url=None, # 默认回调url
# 应用私钥
app_private_key_path=settings.APP_PRIVATE_KEY_PATH,
# 支付宝的公钥,
alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
sign_type="RSA2", # 密码加密的算法
# 开发时属于调试模式
debug = settings.ALIPAY_DEBUG # 默认False
) # verify验证支付结果,布尔值
success = alipay.verify(data, signature) # 修改状态,如更改订单支付时间,支付状态等
if success:
# 支付成功
order = Order.objects.get(order_number=data.get("out_trade_no"))
order.order_status = 1 # 修改订单状态
order.pay_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
order.save() return Response({
"length": order.order_course.count(),
"paytime": order.pay_time,
"price": order.total_price,
"info": order.order_desc,
}, status=status.HTTP_200_OK) return Response({"message": "订单没有变化"})

相关settings的配置信息:

 # 支付宝
ALIPAY_APP_ID="20160********971" # 应用ID
APLIPAY_APP_NOTIFY_URL = None # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面]
APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR,"luffy/apps/payments/keys/app_private_key.pem")
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR,"luffy/apps/payments/keys/alipay_public_key.pem")
ALIPAY_DEBUG = False
# APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do" #上线使用
APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do" #开发使用
ALIPAY_RETURN_URL = "http://127.0.0.1:8080/success"
ALIPAY_NOTIFY_URL = "http://127.0.0.1:8080/success"

Luffy之支付宝支付开发API的更多相关文章

  1. PHP支付宝支付开发流程

    支付宝开发流程   1.首先我们先谈谈第三方支付 所谓第三方支付就是和一些各大银行签约,并具备一定实力和信誉保障的第三方独立机构提供的交易平台 目前市面上常见的有支付宝,财付通,网银,易宝支付等,网站 ...

  2. 微信支付与支付宝支付java开发注意事项

    说明:这里只涉及到微信支付和淘宝支付 以官网的接口为准,主要关注[网关].[接口].[参数][加密方式][签名][回调] 第一步,了解自己的项目要集成的支付方式 常见的有扫码支付.网页支付.APP支付 ...

  3. 前后端分离djangorestframework—— 接入支付宝支付平台

    支付宝 简介 支付宝是什么不用多说了,本次教程适合初学者 前提准备 话不多说,干就完了 1.注册开发者账号,设置公钥私钥 首先进入支付宝开发者平台:传送门 ,有账号直接登录,没账号用你平时用来付款收钱 ...

  4. 支付宝支付之App支付

    与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的. 支付宝开放平台地址:https://docs.open.alipay.com/204/105297/ 支付宝支 ...

  5. 支付宝支付 微信支付SDK接口不统一? 盘他!

      开发过支付宝.微信支付的同学都知道,微信的支付 API 设计感觉是 Java 开发工程师写的,远不如支付宝 SDK 的接口设计用起来顺手.在这里,统一封装微信支付和支付宝支付的API,使两种支付方 ...

  6. iOS开发笔记14:微博/微信登录与分享、微信/支付宝支付

    产品中接入了微博/微信的第三方登录分享功能.微信和支付宝的第三方支付功能,之前在开发过程中涉及到这些部分,于是抽空将接入过程梳理了一遍. 1.微博.微信.支付宝SDK相关接入设置 (1)微博SDK S ...

  7. python 全栈开发,Day102(支付宝支付)

    昨日内容回顾 1. django请求生命周期? - 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者po ...

  8. 移动应用端的支付宝支付php开发流程

    1.https://openhome.alipay.com/ 支付宝开放平台并创建应用,审核通过后并签约app支付拿到pid 2.按照官方文档用 [RSA签名验签工具.bat]生成应用公钥和私钥 3. ...

  9. IOS开发--支付宝支付

    前言:继上次<IOS开发--微信支付>以来,一直没有太多时间,更新总结详细支付这样的长篇大论,很抱歉.今天,推出支付宝支付的详细流程. 1.开始下载和查看支付宝支付的Demo. 我们直接进 ...

随机推荐

  1. Improved GAN

    https://www.bilibili.com/video/av9770302/?p=16 从之前讲的basic gan延伸到unified framework,到WGAN 再到通过WGAN进行Ge ...

  2. 目标检测(七)YOLOv3: An Incremental Improvement

    项目地址 Abstract 该技术报告主要介绍了作者对 YOLOv1 的一系列改进措施(注意:不是对YOLOv2,但是借鉴了YOLOv2中的部分改进措施).虽然改进后的网络较YOLOv1大一些,但是检 ...

  3. Selenium IDE

    Selenium IDE : Selenium IDE作为Firefox浏览器的一款插件,依附于firefox浏览器,打开它的录制功能,它会忠实的记录,你对firefox的操作,并可以回放它所记录的你 ...

  4. Linux常用总结

    CentOS 7.0中一个最主要的改变,就是切换到了systemd.它用于替代红帽企业版Linux前任版本中的SysV和Upstart,对系统和服务进行管理.systemd兼容SysV和Linux标准 ...

  5. [LeetCode] 236. Lowest Common Ancestor of a Binary Tree_ Medium tag: DFS, Divide and conquer

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  6. JavaScript中的BOM和DOM

    javascript组成: 1. ECMAScript 基本语法. 2. BOM (浏览器对象模型) 3. DOM (文档对象模型) 简单的说就是 BOM是浏览器对象模型,用来获取或设置浏览器的属性. ...

  7. egg.js基础入门

    之前一直使用koa, 刚刚接触egg, 做了一些入门的笔记 准备工作 1  首先安装脚手架,,并创建项目. $ npm i egg-init -g $ egg-init egg-demo --type ...

  8. Apriori

    基本概念 项与项集:设itemset={item1, item_2, …, item_m}是所有项的集合,其中,item_k(k=1,2,…,m)成为项.项的集合称为项集(itemset),包含k个项 ...

  9. iptables 认识 第二章

    一.四表五链 netfilter 通过四表五链两个维度来定义数据包过滤规则. #上面图片中 raw 表不在postrouting 链中,请注意 上图中的五个位置也被称为五个钩子函数(hook func ...

  10. 获取从库Seconds_Behind_Master监控主从同步

    #!/bin/bash now_date=`date "+%Y-%m-%d,%H:%M:%S"` flag_old=`cat /home/oracle/scripts/flag.t ...