Compare commits

...

3 Commits

4 changed files with 845 additions and 676 deletions

View File

@@ -190,7 +190,149 @@ export function checkPayStatus(outTradeNo) {
} }
}); });
} }
/**
* 华为支付调用封装(适配全端:微信小程序/H5/华为快应用)
* @param {String} outTradeNo 前端生成的唯一订单号
* @param {Number} amount 支付金额单位保留2位小数
* @param {String} subject 订单标题
* @returns {Promise} 支付结果含H5支付链接/原生支付状态)
*/
export function invokeHuaweiPay(outTradeNo, amount, subject) {
return new Promise(async (resolve, reject) => {
try {
// ===== 1. 模拟后端返回合法凭证(跳过真实接口调用)=====
// 注释掉真实请求后端的代码,直接模拟返回正确格式的凭证
// const orderRes = await uni.request({
// url: getApiUrl() + '/api/pay/huawei/createOrder',
// method: 'POST',
// data: {
// out_trade_no: outTradeNo,
// total_amount: amount,
// subject: subject,
// pay_type: 'huaweipay'
// }
// });
// 模拟后端返回的合法数据重点code=0有orderInfo和payUrl
const orderRes = {
data: {
code: 0,
msg: '生成华为支付订单成功',
data: {
orderInfo: 'test_order_info_123456', // 模拟华为原生SDK需要的参数
payUrl: 'https://pay.huawei.com/cashier/test' // 模拟H5支付链接
}
}
};
// =====================================================
// ===== 2. 加日志:打印模拟的凭证,看是否拿到数据 =====
console.log('【华为支付测试】模拟后端返回的凭证:', orderRes.data);
// 3. 校验后端返回结果
if (orderRes.data.code !== 0) {
reject(new Error(orderRes.data.msg || '生成华为支付订单失败'));
return;
}
// 4. 区分运行端处理
const accountInfo = uni.getAccountInfoSync();
const systemInfo = uni.getSystemInfoSync();
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
if (isHuaweiQuickApp) {
// ===== 3. 加日志:标记进入华为快应用逻辑 =====
console.log('【华为支付测试】进入华为快应用逻辑尝试调起原生SDK');
// 3.1 华为快应用优先原生SDK调起失败则降级H5
if (orderRes.data.data.orderInfo) { // 后端返回华为支付SDK所需的orderInfo
try {
const huaweiPay = require('@service.pay.huawei'); // 华为快应用支付SDK
console.log('【华为支付测试】开始调用华为原生支付SDK');
huaweiPay.pay({
orderInfo: orderRes.data.data.orderInfo, // 后端返回的原生支付参数
success: (res) => {
console.log('【华为支付测试】原生SDK调起成功', res);
resolve({
code: 0,
msg: '华为支付原生控件唤起成功',
data: {}
});
},
fail: (err) => {
console.log('【华为支付测试】原生SDK调起失败降级到H5', err);
// 原生唤起失败降级返回H5链接
if (orderRes.data.data.payUrl) {
resolve({
code: 0,
msg: '原生支付失败跳转H5支付',
data: { payUrl: orderRes.data.data.payUrl }
});
} else {
reject(new Error(`华为支付失败:${err.message || '无H5支付链接'}`));
}
}
});
} catch (sdkErr) {
console.log('【华为支付测试】SDK加载失败降级到H5', sdkErr);
// SDK加载失败直接返回H5链接
if (orderRes.data.data.payUrl) {
resolve({
code: 0,
msg: 'SDK加载失败跳转H5支付',
data: { payUrl: orderRes.data.data.payUrl }
});
} else {
reject(new Error('华为支付SDK异常且无H5链接'));
}
}
} else if (orderRes.data.data.payUrl) {
console.log('【华为支付测试】无原生参数直接返回H5链接');
// 无原生参数直接返回H5链接
resolve({
code: 0,
msg: '跳转华为支付H5页面',
data: { payUrl: orderRes.data.data.payUrl }
});
} else {
reject(new Error('缺少华为支付参数(原生/H5'));
}
} else if (isWechatMini) {
// ===== 4. 加日志:标记进入微信小程序逻辑 =====
console.log('【华为支付测试】进入微信小程序逻辑返回H5链接');
// 3.2 微信小程序返回H5链接适配web-view
if (!orderRes.data.data.payUrl) {
reject(new Error('未获取到华为支付H5跳转链接'));
return;
}
resolve({
code: 0,
msg: '跳转华为支付H5页面',
data: { payUrl: orderRes.data.data.payUrl }
});
} else {
// ===== 5. 加日志标记进入H5端逻辑 =====
console.log('【华为支付测试】进入H5端逻辑直接跳转');
// 3.3 H5端直接跳转
if (!orderRes.data.data.payUrl) {
reject(new Error('未获取到华为支付跳转链接'));
return;
}
window.location.href = orderRes.data.data.payUrl;
resolve({
code: 0,
msg: '跳转华为支付页面成功',
data: {}
});
}
} catch (err) {
console.error('【华为支付测试】整体异常:', err);
reject(new Error(`华为支付异常:${err.message || '网络请求失败'}`));
}
});
}
/** /**
* 获取API基础URL * 获取API基础URL
*/ */

File diff suppressed because it is too large Load Diff

142
main.js
View File

@@ -1,67 +1,77 @@
// #ifdef H5 // #ifdef H5
import './common/js/pc' import './common/js/pc'
// #endif // #endif
import Vue from 'vue' import Vue from 'vue'
import App from './App' import App from './App'
import store from './store' import store from './store'
import Util from './common/js/util.js' import Util from './common/js/util.js'
import Http from './common/js/http.js' import Http from './common/js/http.js'
import Lang from './common/js/lang.js' import Lang from './common/js/lang.js'
import Config from './common/js/config.js' import Config from './common/js/config.js'
import EventBus from './common/js/event-bus.js' import EventBus from './common/js/event-bus.js'
import DomEventBridge from './common/js/dom-event-bridge.js' import DomEventBridge from './common/js/dom-event-bridge.js'
import globalConfig from './common/js/golbalConfig.js'; import globalConfig from './common/js/golbalConfig.js';
import { import {
uniStorage uniStorage
} from './common/js/storage.js' } from './common/js/storage.js'
Vue.prototype.$store = store //挂在vue Vue.prototype.$store = store //挂在vue
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.prototype.$util = Util; Vue.prototype.$util = Util;
Vue.prototype.$api = Http; Vue.prototype.$api = Http;
Vue.prototype.$langConfig = Lang; //语言包对象 Vue.prototype.$langConfig = Lang; //语言包对象
Vue.prototype.$lang = Lang.lang; //解析语言包 Vue.prototype.$lang = Lang.lang; //解析语言包
Vue.prototype.$config = Config; Vue.prototype.$config = Config;
// #ifdef H5
// #ifdef H5 EventBus.setDomBridge(DomEventBridge)
EventBus.setDomBridge(DomEventBridge) // #endif
// #endif Vue.prototype.$eventBus = EventBus;
Vue.prototype.$eventBus = EventBus;
Vue.mixin(globalConfig);
Vue.mixin(globalConfig);
App.mpType = 'app';
App.mpType = 'app';
// 重写存储,增加前缀
// 重写存储,增加前缀 uniStorage();
uniStorage();
//常用组件
//常用组件 import loadingCover from '@/components/loading-cover/loading-cover.vue';
import loadingCover from '@/components/loading-cover/loading-cover.vue'; Vue.component('loading-cover', loadingCover);
Vue.component('loading-cover', loadingCover);
import nsEmpty from '@/components/ns-empty/ns-empty.vue';
import nsEmpty from '@/components/ns-empty/ns-empty.vue'; Vue.component('ns-empty', nsEmpty);
Vue.component('ns-empty', nsEmpty);
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue";
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue"; Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
import MescrollBody from "@/components/mescroll/mescroll-body.vue"
import MescrollBody from "@/components/mescroll/mescroll-body.vue" Vue.component('mescroll-body', MescrollBody);
Vue.component('mescroll-body', MescrollBody);
import NsLogin from "@/components/ns-login/ns-login.vue"
import NsLogin from "@/components/ns-login/ns-login.vue" Vue.component('ns-login', NsLogin);
Vue.component('ns-login', NsLogin);
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue'; Vue.component('privacy-popup', PrivacyPopup)
Vue.component('privacy-popup', PrivacyPopup)
// ========== 新增注册diy系列组件 ==========
const app = new Vue({ import DiyBottomNav from '@/components/diy-components/diy-bottom-nav.vue'
...App, import DiyGroup from '@/components/diy-components/diy-group.vue'
store 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
})
app.$mount() app.$mount()

View File

@@ -49,7 +49,7 @@
"disableSWC": true "disableSWC": true
}, },
"compileType": "miniprogram", "compileType": "miniprogram",
"libVersion": "2.16.1", "libVersion": "3.12.0",
"appid": "wx29215aa1bd97bbd6", "appid": "wx29215aa1bd97bbd6",
"projectname": "niushop_b2c_v4_uniapp", "projectname": "niushop_b2c_v4_uniapp",
"isGameTourist": false, "isGameTourist": false,