7 Commits

5 changed files with 1035 additions and 863 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"codingcopilot.enableCompletionLanguage": {}
}

View File

View File

@@ -73,25 +73,36 @@ export default {
return {
payIndex: 0,
payTypeList: [
// #ifdef H5 || MP-ALIPAY
{
name: '支付宝支付',
icon: 'icon-zhifubaozhifu-',
type: 'alipay'
},
// #endif
// #ifdef H5 || MP-WEIXIN
{
name: '微信支付',
icon: 'icon-weixin1',
type: 'wechatpay'
type: 'wechatpay',
description: '推荐微信用户使用'
},
{
name: '支付宝支付',
icon: 'icon-zhifubaozhifu-',
type: 'alipay',
description: '推荐支付宝用户使用'
},
{
name: '华为支付',
icon: 'icon-huawei-pay',
type: 'huaweipay',
description: '华为用户专属支付'
},
// #endif
{
name: '线下支付',
icon: 'icondiy icon-yuezhifu',
type: 'offlinepay'
type: 'offlinepay',
description: '到店支付或银行转账'
},
{
name: '余额支付',
icon: 'icon-balance',
type: 'balancepay',
description: '使用账户余额支付'
}
],
// #ifdef H5
timer: null,
@@ -105,6 +116,7 @@ export default {
//重置是否已完成没有完成不能调用api/pay/pay
resetPayComplete: true,
repeatFlag: false,
flag: false // 保留文件1的flag变量用于支付失败处理
};
},
created(e) {
@@ -254,42 +266,48 @@ export default {
// #ifdef H5
pay() {
var payType = this.payTypeList[this.payIndex];
// 保留文件2的线下支付逻辑
if (!payType || payType.type === 'offlinepay') {
this.payOffline();
return;
}
// 保留文件2的流程控制
if (!this.resetPayComplete) {
uni.hideLoading();
this.$util.showToast({
title: '支付取消中,请稍后再试!'
});
this.repeatFlag = false;
return;
}
// 复用文件1的核心逻辑调用后端/api/pay/pay接口
var return_url = '';
if (this.payInfo.event == 'BlindboxGoodsOrderPayNotify') {
return_url = '/pages_promotion/blindbox/index?outTradeNo=';
} else {
return_url = '/pages_tool/pay/result?code=';
}
this.$api.sendRequest({
url: '/api/pay/pay',
data: {
out_trade_no: this.payInfo.out_trade_no,
pay_type: payType ? payType.type : '',
pay_type: payType.type,
return_url: encodeURIComponent(this.$config.h5Domain + return_url + this.payInfo.out_trade_no),
is_balance: this.isBalance
},
success: res => {
uni.hideLoading();
this.repeatFlag = false; // 重置文件2的防重复标记
if (res.code >= 0) {
if (res.data.pay_success) {
this.paySuccess();
return;
}
switch (payType.type) {
case 'alipay':
if (this.$util.isWeiXin()) {
var wx_alipay = encodeURIComponent(res.data.data);
this.$util.redirectTo('/pages_tool/pay/wx_pay', {
wx_alipay: wx_alipay,
out_trade_no: this.payInfo.out_trade_no
}, '', 'redirectTo');
this.repeatFlag = false;
} else {
this.repeatFlag = false;
location.href = res.data.data;
this.checkPayStatus();
}
break;
// 保留文件1的微信支付逻辑新增空值判断
case 'wechatpay':
if (this.$util.isWeiXin()) {
if (uni.getSystemInfoSync().platform == 'ios') {
@@ -306,25 +324,29 @@ export default {
success: jssdkRes => {
var wxJS = new Weixin(),
payData = res.data.data;
// 新增空值判断避免读取undefined属性
if (!payData) {
this.$util.showToast({ title: '微信支付参数获取失败' });
this.close();
return;
}
wxJS.init(jssdkRes.data);
wxJS.pay({
timestamp: payData.timestamp ? payData.timestamp : payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign
},
timestamp: payData.timestamp ? payData.timestamp : payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign
},
res => {
if (res.errMsg == 'chooseWXPay:ok') {
this.paySuccess();
this.repeatFlag = false;
} else {
this.$util.showToast({
title: res.errMsg
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
},
@@ -333,41 +355,126 @@ export default {
title: '您已取消支付'
});
this.resetpay();
this.repeatFlag = false;
}
);
}
});
} else {
this.repeatFlag = false;
// 新增判断res.data.url是否存在
if (!res.data.url) {
this.$util.showToast({ title: '微信支付链接获取失败' });
this.close();
return;
}
location.href = res.data.url;
this.checkPayStatus();
}
break;
case 'offlinepay':
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
// 保留文件1的支付宝支付逻辑
case 'alipay':
if (this.$util.isWeiXin()) {
// 新增判断res.data.data是否存在
if (!res.data.data) {
this.$util.showToast({ title: '支付宝支付参数获取失败' });
this.close();
return;
}
var wx_alipay = encodeURIComponent(res.data.data);
this.$util.redirectTo('/pages_tool/pay/wx_pay', {
wx_alipay: wx_alipay,
out_trade_no: this.payInfo.out_trade_no
}, '', 'redirectTo');
} else {
// 新增判断res.data.data是否存在
if (!res.data.data) {
this.$util.showToast({ title: '支付宝支付链接获取失败' });
this.close();
return;
}
location.href = res.data.data;
this.checkPayStatus();
}
break;
// 新增华为支付分支处理沿用文件1范式补充空值判断
case 'huaweipay':
// 新增先判断res.data.data是否存在
if (!res.data.data) {
this.$util.showToast({ title: '华为支付参数获取失败' });
this.close();
return;
}
const systemInfo = uni.getSystemInfoSync();
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei';
// 华为快应用尝试原生SDK唤起
if (isHuaweiQuickApp && res.data.data.orderInfo) {
try {
const huaweiPay = require('@service.pay.huawei');
huaweiPay.pay({
orderInfo: res.data.data.orderInfo,
success: () => {
this.paySuccess();
},
fail: (err) => {
// 原生失败跳H5链接
if (res.data.data.payUrl) {
location.href = res.data.data.payUrl;
this.checkPayStatus();
} else {
this.$util.showToast({
title: `华为支付失败:${err.message}`
});
this.close();
}
}
});
} catch (sdkErr) {
// SDK加载失败跳H5
if (res.data.data.payUrl) {
location.href = res.data.data.payUrl;
this.checkPayStatus();
} else {
this.$util.showToast({
title: '华为支付SDK加载失败'
});
this.close();
}
}
} else if (res.data.data.payUrl) {
// 非华为快应用直接跳H5链接
location.href = res.data.data.payUrl;
this.checkPayStatus();
} else {
this.$util.showToast({
title: '未获取到华为支付链接'
});
this.close();
}
break;
}
} else {
this.$util.showToast({
title: res.message
});
this.repeatFlag = false;
}
},
fail: res => {
uni.hideLoading();
this.repeatFlag = false; // 重置文件2的防重复标记
this.$util.showToast({
title: 'request:fail'
});
this.repeatFlag = false;
}
});
},
/**
* 线下支付处理保留文件2原有逻辑
*/
payOffline() {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
},
checkPayStatus() {
this.timer = setInterval(() => {
this.$api.sendRequest({
@@ -392,114 +499,160 @@ export default {
// #ifdef MP
pay() {
var payType = this.payTypeList[this.payIndex];
// 保留文件2的线下支付逻辑
if (!payType || payType.type === 'offlinepay') {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
return;
}
// 保留文件2的流程控制
if (!this.resetPayComplete) {
uni.hideLoading();
this.$util.showToast({
title: '支付取消中,请稍后再试!'
});
this.repeatFlag = false;
return;
}
// 复用文件1的小程序端核心逻辑调用/api/pay/pay
this.$api.sendRequest({
url: '/api/pay/pay',
data: {
out_trade_no: this.payInfo.out_trade_no,
pay_type: payType ? payType.type : '',
pay_type: payType.type,
scene: uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene,
is_balance: this.isBalance
},
success: res => {
uni.hideLoading();
this.repeatFlag = false; // 重置文件2的防重复标记
if (res.code >= 0) {
if (res.data.pay_success) {
this.paySuccess();
this.repeatFlag = false;
return;
}
if (payType.type == 'offlinepay') {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
} else {
var payData = res.data.data;
var payData = res.data.data;
// #ifdef MP-WEIXIN
var scene = uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene;
if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) {
uni.requestOrderPayment({
timeStamp: payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign,
switch (payType.type) {
// 保留文件1的微信支付逻辑新增空值判断
case 'wechatpay':
// 新增:空值判断
if (!payData) {
this.$util.showToast({ title: '微信支付参数获取失败' });
this.close();
return;
}
var scene = uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene;
if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) {
uni.requestOrderPayment({
timeStamp: payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign,
success: res => {
this.paySuccess();
},
fail: res => {
this.handlePayFail(res);
}
});
return;
}
uni.requestPayment({
provider: 'wxpay',
...payData,
success: res => {
this.paySuccess();
this.repeatFlag = false;
},
fail: res => {
this.flag = false;
if (res.errMsg == 'requestOrderPayment:fail cancel') {
this.$util.showToast({
title: '您已取消支付'
});
this.resetpay();
this.repeatFlag = false;
} else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
this.handlePayFail(res);
}
});
return
}
// #endif
uni.requestPayment({
provider: payType.provider,
...payData,
success: res => {
this.paySuccess();
this.repeatFlag = false;
},
fail: res => {
this.flag = false;
if (res.errMsg == 'requestPayment:fail cancel') {
this.$util.showToast({
title: '您已取消支付'
});
this.resetpay();
this.repeatFlag = false;
} else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
break;
// 保留文件1的支付宝支付逻辑新增空值判断
case 'alipay':
// 新增:空值判断
if (!payData) {
this.$util.showToast({ title: '支付宝支付参数获取失败' });
this.close();
return;
}
});
uni.requestPayment({
provider: 'alipay',
...payData,
success: res => {
this.paySuccess();
},
fail: res => {
this.handlePayFail(res);
}
});
break;
// 新增华为支付小程序端逻辑(补充空值判断)
case 'huaweipay':
// 新增:空值判断
if (!payData) {
this.$util.showToast({ title: '华为支付参数获取失败' });
this.close();
return;
}
if (payData.payUrl) {
// 小程序端跳WebView页面
this.$util.redirectTo('/pages/Pay/Pay', {
payUrl: payData.payUrl,
outTradeNo: this.payInfo.out_trade_no
});
} else {
this.$util.showToast({
title: '未获取到华为支付链接'
});
this.close();
}
break;
}
} else {
this.$util.showToast({
title: res.message
});
this.repeatFlag = false;
}
},
fail: res => {
uni.hideLoading();
this.repeatFlag = false; // 重置文件2的防重复标记
this.$util.showToast({
title: 'request:fail'
});
this.repeatFlag = false;
}
});
},
/**
* 统一处理支付失败复用文件1逻辑
*/
handlePayFail(res) {
this.flag = false;
if (res.errMsg.includes('cancel')) {
this.$util.showToast({
title: '您已取消支付'
});
this.resetpay();
} else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
}, 1500)
}
},
// #endif
/**
* 支付成功之后跳转
* 支付成功之后跳转(真实业务逻辑)
*/
paySuccess() {
if (this.payInfo.event == 'BlindboxGoodsOrderPayNotify') {
@@ -516,7 +669,7 @@ export default {
}
},
/**
* 重置支付单据
* 重置支付单据(真实业务逻辑)
*/
resetpay() {
this.resetPayComplete = false;
@@ -643,6 +796,9 @@ export default {
.icon-zhifubaozhifu- {
color: #00a0e9;
}
.icon-huawei-pay {
color: #c7000b; // 华为支付品牌色
}
.icon-checkboxblank {
font-size: 40rpx;

12
main.js
View File

@@ -27,7 +27,6 @@ Vue.prototype.$lang = Lang.lang; //解析语言包
Vue.prototype.$config = Config;
// #ifdef H5
EventBus.setDomBridge(DomEventBridge)
// #endif
@@ -59,6 +58,17 @@ Vue.component('ns-login', NsLogin);
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
Vue.component('privacy-popup', PrivacyPopup)
// ========== 新增注册diy系列组件 ==========
import DiyBottomNav from '@/components/diy-components/diy-bottom-nav.vue'
import DiyGroup from '@/components/diy-components/diy-group.vue'
import DiyCategory from '@/components/diy-components/diy-category.vue'
import DiyIcon from '@/components/diy-components/diy-icon.vue' // 补充diy-icon
Vue.component('diy-bottom-nav', DiyBottomNav) // 修正拼写错误
Vue.component('diy-group', DiyGroup)
Vue.component('diy-category', DiyCategory)
Vue.component('diy-icon', DiyIcon) // 注册diy-icon
// ========== 新增结束 ==========
const app = new Vue({
...App,
store

View File

@@ -1,7 +1,8 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
"ignore": [],
"include": []
},
"setting": {
"urlCheck": true,
@@ -37,20 +38,20 @@
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true
"minifyWXSS": true,
"compileWorklet": false,
"minifyWXML": true,
"localPlugins": false,
"disableUseStrict": false,
"useCompilerPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true
},
"compileType": "miniprogram",
"libVersion": "2.16.1",
"libVersion": "3.12.0",
"appid": "wx29215aa1bd97bbd6",
"projectname": "niushop_b2c_v4_uniapp",
"debugOptions": {
"hidedInDevtools": []
},
"scripts": {},
"staticServerOptions": {
"baseURL": "",
"servePath": ""
},
"isGameTourist": false,
"condition": {
"search": {
@@ -71,5 +72,7 @@
"miniprogram": {
"list": []
}
}
},
"simulatorPluginLibVersion": {},
"editorSetting": {}
}