功能完成

This commit is contained in:
Xubx 2024-09-04 23:56:21 +08:00
parent 663be8f39f
commit 7e90cc1757
13 changed files with 209 additions and 99 deletions

2
app.js
View File

@ -1,4 +1,4 @@
const baseUrl = "http://localhost:8080" const baseUrl = "http://localhost:8082"
App({ App({

6
cloud/pay/config.json Normal file
View File

@ -0,0 +1,6 @@
{
"permissions": {
"openapi": [
]
}
}

22
cloud/pay/index.js Normal file
View File

@ -0,0 +1,22 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
console.log("有进来")
const res = await cloud.cloudPay.unifiedOrder({
"functionName": "pay_success", // 支付结果通知回调云函数名
"envId": "zdt2024-9g7pr48u64f887f0", // 结果通知回调云函数环境
"subMchId": "1684540409", // 商户号
"nonceStr": event.nonceStr,//随机字符串,主要保证签名不可预测
"body": "解锁悄悄话", // 商品描述
"outTradeNo": event.outTradeNo, // 商户订单号
"totalFee": event.totalFee, // 总金额
"spbillCreateIp": "127.0.0.1", // 终端 IP,社区说可以随便填不知道为什么可能会出bug
"tradeType": "JSAPI",//交易类型
})
console.log("这里" + res)
return res
}

14
cloud/pay/package.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "pay",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

View File

@ -0,0 +1,6 @@
{
"permissions": {
"openapi": [
]
}
}

View File

@ -0,0 +1,25 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
const returnCode = event.returnCode
const openid = event.userInfo.openid
const orderid = event.outTradeNo
const db = cloud.database();
if (returnCode == 'SUCCESS') {
//支付成功的处理逻辑
// await db.collection("orders").where({
// _id: orderid,
// _openid: openid,
// }).update({
// data: {
// pay_status: true
// }
// })
const res = { errCode: 0, errmag: "6666666办款完毕" }
return res
}
}

View File

@ -0,0 +1,14 @@
{
"name": "pay_success",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

View File

@ -11,7 +11,7 @@ Page({
onLoad(options) { onLoad(options) {
const goods = { const goods = {
id: options.id, id: options.goodsId,
goodName: options.goodName, goodName: options.goodName,
goodPrice: options.goodPrice, goodPrice: options.goodPrice,
goodDetail: options.goodDetail, goodDetail: options.goodDetail,
@ -109,7 +109,7 @@ Page({
const { id, goodName, goodImage, goodPrice } = this.data.goods; const { id, goodName, goodImage, goodPrice } = this.data.goods;
const num = this.data.buyNum; const num = this.data.buyNum;
const url = `../orders/orders?id=${id}&title=${goodName}&image=${goodImage[0]}&price=${goodPrice}&num=${num}&specs=${this.data.selectedSpecs.join(',')}`; const url = `../orders/orders?goodsId=${id}&title=${goodName}&image=${goodImage[0]}&price=${goodPrice}&num=${num}&specs=${this.data.selectedSpecs.join(',')}`;
wx.navigateTo({ url }); wx.navigateTo({ url });
// }, // },

View File

@ -45,32 +45,31 @@ Page({
openId: wx.getStorageSync('openid'), openId: wx.getStorageSync('openid'),
}, },
success(res) { success(res) {
console.log(res.data.data) console.log("查到的用户信息" + res.data.data)
// 将用户信息存到 StorageSync if (res.data.data != null) {
const userInfo = { // 将用户信息存到 StorageSync
avatarUrl: res.data.data.avatarUrl, const userInfo = {
nickName: res.data.data.username avatarUrl: res.data.data.avatarUrl,
}; nickName: res.data.data.username
wx.setStorageSync('userInfo', userInfo); // 存储到本地 };
}, wx.setStorageSync('userInfo', userInfo); // 存储到本地
fail: (err) => { } else {
// 没有用户信息,提示用户登录授权 wx.showModal({
wx.showModal({ title: '温馨提示',
title: '温馨提示', content: '请先登录!',
content: '请先登录!', showCancel: false,
showCancel: false, success: (res) => {
success: (res) => { if (res.confirm) {
if (res.confirm) { console.log(res)
console.log(res) wx.navigateTo({
wx.navigateTo({ url: '/page/component/login/login',
url: '/page/component/login/login', });
}); }
} }
} })
}); }
} }
}) })
} }
}, },
//获取openId //获取openId
@ -80,12 +79,14 @@ Page({
success: (res) => { success: (res) => {
const wxConfig = { const wxConfig = {
appid: "wx865aefa5a7115ae0", appid: "wx865aefa5a7115ae0",
secret: "3f9849429894435abc935eea88178dfd", secret: "df0817d59696a6160de2770222d8ec53",
code: res.code code: res.code
} }
console.log("code: " + res.code)
wx.request({ wx.request({
url: "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxConfig.appid + "&secret=" + wxConfig.secret + "&code=" + wxConfig.code + "&js_code=" + wxConfig.code + '&grant_type=authorization_code', url: "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxConfig.appid + "&secret=" + wxConfig.secret + "&code=" + wxConfig.code + "&js_code=" + wxConfig.code + '&grant_type=authorization_code',
success: (res) => { success: (res) => {
console.log("openid:" + res.data.openId)
wx.setStorageSync('openid', res.data.openid); wx.setStorageSync('openid', res.data.openid);
}, },
fail: (err) => { fail: (err) => {

View File

@ -39,7 +39,7 @@
<view class="newest-box"> <view class="newest-box">
<view class="newest-list"> <view class="newest-list">
<view class="item" wx:for="{{goods}}" wx:key="id"> <view class="item" wx:for="{{goods}}" wx:key="id">
<navigator url="details/details?id={{item.id}}&goodImage={{item.goodImage}}&goodName={{item.goodName}}&goodPrice={{item.goodPrice}}&goodDetail={{item.goodDetail}}"> <navigator url="details/details?goodsId={{item.id}}&goodImage={{item.goodImage}}&goodName={{item.goodName}}&goodPrice={{item.goodPrice}}&goodDetail={{item.goodDetail}}">
<view class="list"> <view class="list">
<image src="{{item.goodImage}}"></image> <image src="{{item.goodImage}}"></image>
<view class="newest-text"><text>{{item.goodName}}</text></view> <view class="newest-text"><text>{{item.goodName}}</text></view>

View File

@ -1,6 +1,6 @@
<view class="main"> <view class="main">
<view class="orders-box"> <view class="orders-box">
<navigator wx:for="{{orders}}" wx:key="id" url="../orders/orders?id={{item.goodsId}}&title={{item.goodName}}&price={{item.goodPrice}}&num={{item.num}}&image={{item.goodImage}}&specs={{item.specs}}"> <navigator wx:for="{{orders}}" wx:key="id" url="../orders/orders?goodsId={{item.goodsId}}&title={{item.goodName}}&price={{item.goodPrice}}&num={{item.num}}&image={{item.goodImage}}&specs={{item.specs}}">
<view class="orders-list"> <view class="orders-list">
<image class="orders-thumb" src="{{item.goodImage}}"></image> <image class="orders-thumb" src="{{item.goodImage}}"></image>
<view class="orders-info"> <view class="orders-info">

View File

@ -6,7 +6,7 @@ const md5 = require('js-md5');
Page({ Page({
onLoad: function (options) { onLoad: function (options) {
const orders = { const orders = {
id: options.id, goodsId: options.goodsId,
title: options.title, title: options.title,
price: options.price, price: options.price,
num: options.num, num: options.num,
@ -70,27 +70,14 @@ Page({
} }
return pwd; return pwd;
}, },
// 调起支付签名 这里我不太明白,虽然前面加载签名和后面验证,但里面加了随机数为什么验证还能通过我没还转过 弯来,希望大家能搞明白吧,到时候可不要吝啬留言讲解一下下
MixedencryMD5: function (data, randomString, timeStamp) {
const payString = "appId=" + this.data.config.appid +
"&nonceStr=" + randomString +
"&package=prepay_id=" + "data.prepay_id" +
"&signType=MD5" +
"&timeStamp=" + timeStamp +
"&key=" + this.data.config.key;
const hash = md5(payString); // 使用 md5 进行签名
console.log(hash);
return hash;
},
toPay() { toPay() {
const self = this; const self = this;
const orderData = this.data.orders; const orderData = this.data.orders;
// 假设用户ID暂时写死 // 假设用户ID暂时写死
orderData.userId = 1; orderData.openId = wx.getStorageSync('openid');
orderData.status = 1; orderData.status = 1;
console.log("orderData", orderData)
// 生成订单并请求支付 // 生成订单并请求支付
wx.request({ wx.request({
url: baseUrl + "/order/addOrUpdate", // 替换为你的后端API地址 url: baseUrl + "/order/addOrUpdate", // 替换为你的后端API地址
@ -103,63 +90,96 @@ Page({
}, },
success(res) { success(res) {
if (res.statusCode === 200) { if (res.statusCode === 200) {
wx.showToast({ console.log(res)
title: "订单已提交", wx.cloud.init({
icon: "success", env: 'zdt2024-9g7pr48u64f887f0', //填上你的云开发环境id
duration: 2000, traceUser: true,
}); });
// 假设服务器返回的支付信息中包含 prepay_id
const paymentInfo = res.data.paymentInfo; // 服务器返回的支付信息,包含 prepay_id 等
// 生成支付签名等所需的参数(最好在服务器生成)
const time = self.timeStamp()
const randomString = self.randomString(); const randomString = self.randomString();
const parSigns = self.MixedencryMD5(paymentInfo, randomString, time); const outTradeNo = res.data.data.orderCode
const orderId = res.data.data.id
// 发起支付请求 wx.cloud.callFunction({
wx.requestPayment({ name: "pay",
timeStamp: time, data: {
nonceStr: randomString, nonceStr: randomString, //随机字符串,String(32)
package: "prepay_id=" + "paymentInfo.prepay_id", outTradeNo: outTradeNo, //商户订单号,String(32)
signType: "MD5", totalFee: self.data.total, //Int
paySign: parSigns, },
success(ress) { success: res => {
console.log('支付成功', ress); console.log('下单结果: ', res);
// 支付成功后的处理,跳转到用户页面或其他页面 // 获取到预付单信息
wx.switchTab({ const payment = res.result.payment
url: "/page/component/user/user", wx.hideLoading();
// 唤起微信支付组件,完成支付
wx.requestPayment({
...payment, //把payment展开
success(res) {
// 支付成功回调,实现自定义的业务逻辑
console.log('唤起支付组件成功:', res);
// 将订单的status改为已支付
orderData.status = 2;
orderData.id = orderId;
wx.request({
url: baseUrl + "/order/addOrUpdate", // 替换为你的后端API地址
method: "POST",
data: {
...orderData,
},
header: {
"Content-Type": "application/json", // 设置请求头
},
success(res) {
wx.showToast({
title: "订单支付成功",
icon: "success",
duration: 2000,
});
wx.switchTab({
url: '/page/component/index', // 替换为你的首页路径
});
}
})
},
fail(err) {
// 支付失败回调
console.error('唤起支付组件失败:', err);
// 将订单的status改为已关单
orderData.status = 0;
orderData.id = orderId;
wx.request({
url: baseUrl + "/order/addOrUpdate", // 替换为你的后端API地址
method: "POST",
data: {
...orderData,
},
header: {
"Content-Type": "application/json", // 设置请求头
},
success(res) {
wx.showToast({
title: "订单支付成功",
icon: "success",
duration: 2000,
});
wx.switchTab({
url: '/page/component/index', // 替换为你的首页路径
});
}
})
wx.showToast({
title: "支付失败",
icon: "error",
duration: 2000,
});
}
}); });
}, },
fail(ress) { fail: err => {
console.log('支付失败', ress); console.log(err)
wx.showToast({
title: "支付失败,请重试",
icon: "none",
duration: 2000,
});
},
complete(ress) {
console.log('支付流程结束', ress);
} }
}); })
} else {
wx.showToast({
title: "提交失败",
icon: "none",
duration: 2000,
});
} }
}, }
fail() { })
wx.showToast({ }
title: "请求失败",
icon: "none",
duration: 2000,
});
},
});
},
}) })

View File

@ -1,5 +1,6 @@
{ {
"description": "项目配置文件。", "description": "项目配置文件。",
"cloudfunctionRoot": "cloud/",
"packOptions": { "packOptions": {
"ignore": [], "ignore": [],
"include": [] "include": []
@ -33,5 +34,6 @@
"editorSetting": { "editorSetting": {
"tabIndent": "insertSpaces", "tabIndent": "insertSpaces",
"tabSize": 2 "tabSize": 2
} },
"cloudfunctionTemplateRoot": "cloudfunctionTemplate/"
} }