Django == 3.1.0
python == 3.7.4
python-alipay-sdk=2.0.1
# 支付状态表
class Status(BaseModel):
name = models.CharField(max_length=32)
class Meta:
db_table = 'status'
# 支付表
class Order(BaseModel):
out_trade_no = models.CharField(max_length=60)
trada_no = models.CharField(max_length=60, null=True, blank=True)
goods = models.ForeignKey(Goods, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
goods_num = models.IntegerField()
status = models.ForeignKey(Status, on_delete=models.CASCADE)
class Meta:
db_table = 'order'
所需的包
import uuid
import redis
from app01.views import login_serializer
from alipay import AliPay, AliPayConfig
# 绝对路径打开文件 {}代表从这里往前
app_private_key_string = open('{}\\app02\\alipay_key\\app_private_key'.format(settings.BASE_DIR)).read()
alipay_public_key_string = open('{}\\app02\\alipay_key\\alipay_public'.format(settings.BASE_DIR)).read()
alipay = AliPay(
appid="2016102500759596",
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_string,
# 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
alipay_public_key_string=alipay_public_key_string,
sign_type="RSA2", # RSA 或者 RSA2
debug=True, # 默认False
config=AliPayConfig(timeout=15) # 可选, 请求超时时间
)
3.注释的代码可以去掉
# 支付
class AlipayView(APIView):
def post(self, request):
# print(request.data)
token = request.data.get('token')
count = request.data.get('count')
goods_info = request.data.get('goods_info')
# print(goods_info)
# 订单号 uuid唯一不重复
out_trade_no = str(uuid.uuid4())
# 订单金额初始
total_amount = 0
user_info = login_serializer.loads(token)
user_id = user_info.get('user_id')
# 判断是否是多个id 用,号分割
if goods_info.find(',') != -1:
order_list = []
for i in goods_info.split(','):
print(i)
# 循环输出id
# # 获取购物车商品数量
# goods_count = r3.hget(user_id, i).decode()
# # get到等于i的商品
# goods_obj = Goods.objects.get(pk=i)
# # 计算总价
# total_amount += int(goods_obj.price) * int(goods_count)\
# 列表添加类型
order_list.append(Order(
out_trade_no=out_trade_no,
goods_id=i,
user_id=user_id,
goods_num=count,
status_id=1,
))
print(order_list)
# 批量添加 列表
ser = Order.objects.bulk_create(order_list)
# ser.save()
else:
# print(r3.hget(user_id, goods_info))
# goods_count = r3.hget(user_id, goods_info).decode()
# goods_obj = Goods.objects.get(pk=goods_info)
# total_amount += int(goods_obj.price) * int(goods_count)
# print(total_amount)
# 单个添加
ser = OrderModelSer(data={
"out_trade_no": out_trade_no,
"goods": goods_info,
"user": user_id,
"goods_num": count,
"status": 1
})
if ser.is_valid():
ser.save()
else:
print(ser.errors)
# 主题
subject = "京东"
# 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=out_trade_no,
total_amount=count,
subject=subject,
return_url="http://127.0.0.1:8000/app02/callback_alipay",
notify_url="http://127.0.0.1:8000/app02/callback_alipay" # 可选, 不填则使用默认notify url
)
# 拼接的数据
# print(order_string)
pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
# 带参数跳转的路由
# print(pay_url)
return Response({
'pay_url': pay_url, 'msg': 'OK', "code": 200})
# 支付完回调地址
class CallBackAlipayView(APIView):
def get(self, request):
print(request.query_params)
print("------------------------------")
# 判断是否有数据
if request.query_params.get("sign"):
# for i in request.query_params.get("out_trade_no"):
# print(request.query_params.get("out_trade_no"))
# 获取订单号
queryset = Order.objects.get(out_trade_no=request.query_params.get("out_trade_no"))
# 修改订单状态为已购买 局部修改
ser = OrderModelSer(instance=queryset, data={
"status": 2}, partial=True)
if ser.is_valid():
ser.save()
else:
print(ser.errors)
return Response({
'msg': 'OK', "data": request.query_params})
addcart() {
let data = new FormData();
data.append("token", sessionStorage.getItem("token"))
data.append("goods_info", this.check)
data.append("count", this.count2)
axios({
url: "http://127.0.0.1:8000/app02/alipay",
method: 'post',
data: data
}).then(res => {
console.log(res.data)
if (res.data.code === 200) {
window.location.href = res.data.pay_url
}
})
},
<template>
<div>
<div id="app">
<div class="header_con">
<div class="header">
<div class="welcome fl">欢迎来到美多商城!</div>
<div class="fr">
<div v-if="username" class="login_btn fl">
欢迎您:<em>{
{
username }}</em>
<span>|</span>
<a @click="logout">退出</a>
</div>
<div v-else class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="user_center_info.html">用户中心</a>
<span>|</span>
<a href="cart.html">我的购物车</a>
<span>|</span>
<a href="user_center_order.html">我的订单</a>
</div>
</div>
</div>
</div>
<div class="search_bar clearfix">
<a href="index.html" class="logo fl"><img src="/static/images/logo.png"></a>
<div class="sub_page_name fl">| 购物车</div>
<form method="get" action="/search.html" class="search_con fr mt40">
<input type="text" class="input_text fl" name="q" placeholder="搜索商品">
<input type="submit" class="input_btn fr" name="" value="搜索">
</form>
</div>
<div class="total_count">全部商品<em>{
{
cart.length}}</em>件</div>
<ul class="cart_list_th clearfix">
<li class="col01">商品名称</li>
<li class="col03">商品价格</li>
<li class="col04">数量</li>
<li class="col05">小计</li>
<li class="col06">操作</li>
</ul>
<ul class="cart_list_td clearfix" v-for="(sku,index) in cart">
<li class="col01"><input type="checkbox" name="" v-model="check" :value="sku.id"
@click="checkbox(sku.id,sku.count,sku.price)"></li>
<li class="col02"><img :src="'http://127.0.0.1:8000'+sku.img"></li>
<li class="col03">{
{
sku.name }}</li>
<li class="col05">{
{
sku.price }}元</li>
<li class="col06">
<div class="num_add">
<a @click="on_add(sku.id)" class="add fl">+</a>
<input v-model="sku.count" @focus="origin_input=sku.count" @blur="on_input(index)" type="text"
class="num_show fl">
<a @click="on_minus(sku.id)" class="minus fl">-</a>
</div>
</li>
<li class="col07">{
{
sku.price * sku.count}}元</li>
<li class="col08"><a @click="del(sku.id)">删除</a></li>
</ul>
<ul class="settlements">
<li class="col01"><input type="checkbox" @click="check_count" v-model="isChecked"></li>
<li class="col02">全选</li>
<li class="col03">合计(不含运费):<span>¥</span><em>{
{
count2}}</em><br>共计<b>{
{
total_selected_count}}</b>件商品
</li>
<li class="col04"><a @click="addcart">去结算</a></li>
</ul>
</div>
<fooder></fooder>
</div>
</template>
<script>
import axios from 'axios'
import fooder from '../components/Fooder'
export default {
name: "Cart",
data() {
return {
cart: [
],
check: [],
username: "",
total_selected_amount: "",
total_selected_count: "",
on_selected_all: "",
selected_all: "",
count2: 0,
isChecked: false,
}
},
components: {
'fooder': fooder
},
methods: {
del(goods_id) {
let data = new FormData();
data.append("token", sessionStorage.getItem("token"))
data.append("goods_id", goods_id)
axios({
url: 'http://127.0.0.1:8000/app02/delcart',
method: 'delete',
data: data
}).then(res => {
console.log(res)
this.$router.go(0)
})
},
addcart() {
let data = new FormData();
data.append("token", sessionStorage.getItem("token"))
data.append("goods_info", this.check)
data.append("count", this.count2)
axios({
url: "http://127.0.0.1:8000/app02/alipay",
method: 'post',
data: data
}).then(res => {
console.log(res.data)
if (res.data.code === 200) {
window.location.href = res.data.pay_url
}
})
},
on_add(goods_id) {
let data = new FormData();
data.append("token", sessionStorage.getItem("token"))
data.append("goods_id", goods_id)
axios({
url: 'http://127.0.0.1:8000/app02/addcart',
method: 'post',
data: data
}).then(res => {
console.log(res)
this.$router.go(0)
})
},
on_minus(goods_id) {
let data = new FormData();
data.append("token", sessionStorage.getItem("token"))
data.append("goods_id", goods_id)
axios({
url: 'http://127.0.0.1:8000/app02/minuscart',
method: 'post',
data: data
}).then(res => {
console.log(res)
this.$router.go(0)
})
},
show() {
axios({
url: 'http://127.0.0.1:8000/app02/showcart',
method: 'get',
params: {
"token": sessionStorage.getItem("token")}
}).then(res => {
console.log(res)
this.cart = res.data.data
})
},
//全选并调用总价
check_count() {
//默认值为false
this.count2 = 0;
this.check = [];
if (this.isChecked) {
this.check = []
} else {
this.cart.forEach(item => {
console.log(item.id);
this.check.push(item.id);
this.count()
})
}
},
//计算总价
count() {
// let count = 0
this.count2 = 0
for (let i in this.cart) {
console.log(this.cart[i])
this.count2 += this.cart[i].price * this.cart[i].count
}
},
//计算单选框
checkbox(gid, count, price) {
//第一次执行都为空 false
console.log(this.check)
if (this.check.includes(gid)) {
// 包含则说明已经选中 再次点击删除 false 并减去相应的价格
this.count2 -= count * price
this.check.splice(this.check.indexOf(gid), 1)
} else {
//推送 也就是添加 变为true
this.check.push[gid]
//计算总价 选中相加
this.count2 += count * price
}
},
},
created() {
this.show()
}
}
</script>
<style scoped>
</style>
次点击删除 false 并减去相应的价格
this.count2 -= count * price
this.check.splice(this.check.indexOf(gid), 1)
} else {
//推送 也就是添加 变为true
this.check.push[gid]
//计算总价 选中相加
this.count2 += count * price
}
},
},
created() {
this.show()
}
}
</script>
<style scoped>
</style>