init
|
|
@ -0,0 +1 @@
|
||||||
|
unpackage/
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
globalData: {
|
||||||
|
token: '',
|
||||||
|
},
|
||||||
|
onLaunch: function() {
|
||||||
|
console.log('App Launch')
|
||||||
|
},
|
||||||
|
onShow: function() {
|
||||||
|
console.log('App Show')
|
||||||
|
},
|
||||||
|
onHide: function() {
|
||||||
|
console.log('App Hide')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/*每个页面公共css */
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
CSS.supports('top: constant(a)'))
|
||||||
|
document.write(
|
||||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
// const BASE_URL = 'https://u.batiao8.com' //测试
|
||||||
|
const BASE_URL = 'https://pay.batiao8.com' //正式
|
||||||
|
export default BASE_URL
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import BASE_URL from './baseUrl.js'
|
||||||
|
|
||||||
|
const request = async ({
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
data
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const app = getApp();
|
||||||
|
const globalData = app.globalData || {}
|
||||||
|
let header = {};
|
||||||
|
if (globalData.token) {
|
||||||
|
header['x-token'] = globalData.token;
|
||||||
|
}
|
||||||
|
let res = await uni.request({
|
||||||
|
url: BASE_URL + url,
|
||||||
|
method: method,
|
||||||
|
data: data,
|
||||||
|
// header: header
|
||||||
|
})
|
||||||
|
console.log('--res', res)
|
||||||
|
if (res.data) {
|
||||||
|
if(res.data.code && res.data.code !== 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message.split(',')[0],
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return res.data
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message,
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('--err', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: err.errMsg,
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import App from './App'
|
||||||
|
|
||||||
|
// #ifndef VUE3
|
||||||
|
import Vue from 'vue'
|
||||||
|
import './uni.promisify.adaptor'
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
App.mpType = 'app'
|
||||||
|
const app = new Vue({
|
||||||
|
...App
|
||||||
|
})
|
||||||
|
app.$mount()
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef VUE3
|
||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
return {
|
||||||
|
app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
{
|
||||||
|
"name" : "batiao-pay",
|
||||||
|
"appid" : "",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.0",
|
||||||
|
"versionCode" : "100",
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : true,
|
||||||
|
"waiting" : true,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"distribute" : {
|
||||||
|
/* android打包配置 */
|
||||||
|
"android" : {
|
||||||
|
"permissions" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wxb0e5bc0e275ba55c",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true,
|
||||||
|
"appid" : "2021005194639068"
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
"uniIdRouter": {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,412 @@
|
||||||
|
<template>
|
||||||
|
<view class="wrapper" style="height: 100vh">
|
||||||
|
<!-- 浏览器不支持提示 -->
|
||||||
|
<view class="wrapper" id="pay-result" style="background: #fff" v-if="envErrType">
|
||||||
|
<view class="pay-result-container">
|
||||||
|
<image src="/static/image/payerr.png" style="width: 96px; height: 96px"></image>
|
||||||
|
<view class="env-err-text">{{ envErrText }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="wrapper" id="pay-result" style="background: #fff" v-else-if="orderInfo.status === 2">
|
||||||
|
<view class="pay-result-container">
|
||||||
|
<image v-if="browerEnv === 'alipay'" src="/static/image/ali-payok.png" style="width: 96px; height: 96px"></image>
|
||||||
|
<image v-if="browerEnv === 'weixin'" src="/static/image/wx-payok.png" style="width: 96px; height: 96px"></image>
|
||||||
|
<view class="pay-result-text">支付已完成</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 支付页面 -->
|
||||||
|
<view class="wrapper" id="pay-page" v-else-if="currentPage === 'pay-page'">
|
||||||
|
<view class="item-name">{{ orderInfo.goodsName }}</view>
|
||||||
|
<view class="item-count">
|
||||||
|
<text style="font-size: 26px">¥ </text>{{ numberFormat(orderInfo.totalFee) }}
|
||||||
|
</view>
|
||||||
|
<!-- <view class="company">重庆八条科技有限公司</view> -->
|
||||||
|
|
||||||
|
<!-- 支付按钮 -->
|
||||||
|
<view class="pay-methods">
|
||||||
|
<view v-for="item in payMethodList" :key="item.id" class="pay-method-item">
|
||||||
|
<view class="pay-method-item-left">
|
||||||
|
<image :src="item.logo" style="width: 30px; height: 30px"></image>
|
||||||
|
<text class="pay-method-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="pay-method-item-right">
|
||||||
|
<image :src="item.checkIcon" style="width: 18px; height: 18px"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button id="pay-btn" :class="[`${browerEnv}-btn`]" @click="goPay">
|
||||||
|
立即支付
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 支付结果页面 -->
|
||||||
|
<view class="wrapper" id="pay-result" style="background: #fff" v-else-if="currentPage === 'pay-result'">
|
||||||
|
<view class="pay-result-container">
|
||||||
|
<image :src="payResultItem.icon" style="width: 96px; height: 96px"></image>
|
||||||
|
<view class="pay-result-text">{{ payResultItem.resultText }}</view>
|
||||||
|
<button v-if="fromApp" class="back-btn" open-type="launchApp" app-parameter="wechat" :binderror="launchAppError">返回APP</button>
|
||||||
|
<button v-else class="back-btn" :style="payResultItem.style" @click="goBackPay">
|
||||||
|
{{ payResultItem.backText }}
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import request from "@/lib/request.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
authCode: '',
|
||||||
|
encOrderId: "",
|
||||||
|
outTradeNo: "",
|
||||||
|
browerEnv: "",
|
||||||
|
orderInfo: {},
|
||||||
|
currentPage: "pay-page",
|
||||||
|
paySuccess: true,
|
||||||
|
payMethodList: [{
|
||||||
|
name: "支付宝支付",
|
||||||
|
id: "alipay",
|
||||||
|
logo: "/static/image/ali-logo.png",
|
||||||
|
checkIcon: "/static/image/ali-check.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "微信支付",
|
||||||
|
id: "weixin",
|
||||||
|
logo: "/static/image/wx-logo.png",
|
||||||
|
checkIcon: "/static/image/wx-check.png",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timer: null,
|
||||||
|
fromApp: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
payResultList() {
|
||||||
|
return [{
|
||||||
|
icon: "/static/image/payerr.png",
|
||||||
|
resultText: "抱歉,订单支付失败",
|
||||||
|
backText: "重新支付",
|
||||||
|
style: {background: this.browerEnv === "weixin" ? '#05bf5e' : '#2c78fe', color: '#fff'},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: this.browerEnv === "weixin" ?
|
||||||
|
"/static/image/wx-payok.png" : "/static/image/ali-payok.png",
|
||||||
|
resultText: "支付成功",
|
||||||
|
backText: "返回",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
payResultItem() {
|
||||||
|
return this.paySuccess ? this.payResultList[1] : this.payResultList[0];
|
||||||
|
},
|
||||||
|
envErrType() {
|
||||||
|
if(!this.browerEnv) return '';
|
||||||
|
if (this.browerEnv === "browser") {
|
||||||
|
return "envErr:browser";
|
||||||
|
} else if (!this.encOrderId && !this.outTradeNo) {
|
||||||
|
return "envErr:noParams";
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
envErrText() {
|
||||||
|
const group = {
|
||||||
|
"envErr:browser": "不支持浏览器,请使用支付宝或微信重新扫码",
|
||||||
|
"envErr:noParams": "请通过扫描二维码使用小程序",
|
||||||
|
"envErr:outTradeNo": "获取订单信息失败",
|
||||||
|
};
|
||||||
|
return group[this.envErrType];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
launchAppError(e) {
|
||||||
|
console.log(e.detail.errMsg)
|
||||||
|
},
|
||||||
|
numberFormat(value) {
|
||||||
|
if (value) return value.toFixed(2);
|
||||||
|
return "0.00";
|
||||||
|
},
|
||||||
|
// 获取支付宝用户信息
|
||||||
|
getAliUserInfo() {
|
||||||
|
// 检查是否已授权
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
my.getAuthCode({
|
||||||
|
scopes: ["auth_base"],
|
||||||
|
success: (res) => {
|
||||||
|
console.log("获取授权码成功", res);
|
||||||
|
this.authCode = res.authCode;
|
||||||
|
},
|
||||||
|
fail: (error) => {
|
||||||
|
console.error("获取授权码失败", error);
|
||||||
|
uni.showToast({
|
||||||
|
icon: "none",
|
||||||
|
title: "获取授权码失败",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 获取微信用户信息
|
||||||
|
getWxUserInfo() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.getProvider({
|
||||||
|
service: 'oauth',
|
||||||
|
success: (res) => {
|
||||||
|
console.log('getProvider', res.provider)
|
||||||
|
uni.login({
|
||||||
|
provider: res.provider,
|
||||||
|
success: (loginRes) => {
|
||||||
|
this.authCode = loginRes.code
|
||||||
|
console.log('loginRes', this.authCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 支付按钮点击事件
|
||||||
|
async goPay() {
|
||||||
|
uni.showLoading()
|
||||||
|
try {
|
||||||
|
// 应用下单
|
||||||
|
const {
|
||||||
|
outTradeNo,
|
||||||
|
paySource = "jsapi"
|
||||||
|
} = this.orderInfo;
|
||||||
|
let extra = {};
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
extra.alipayAuthCode = this.authCode;
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
extra.weixinAuthCode = this.authCode;
|
||||||
|
// #endif
|
||||||
|
console.log('authCode',this.authCode)
|
||||||
|
if (!this.authCode) {
|
||||||
|
console.error("没有授权码");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let orderData = await this.handleOrder({
|
||||||
|
outTradeNo,
|
||||||
|
payType: this.browerEnv,
|
||||||
|
paySource: paySource,
|
||||||
|
extra,
|
||||||
|
});
|
||||||
|
let tradeNo = orderData.tradeNo;
|
||||||
|
console.log("tradeNo", tradeNo);
|
||||||
|
if(this.browerEnv === 'alipay') {
|
||||||
|
// 调起支付宝支付
|
||||||
|
let res = await this.handleAlipay({
|
||||||
|
tradeNO: tradeNo,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('支付宝支付成功', res)
|
||||||
|
} else if(this.browerEnv === 'weixin') {
|
||||||
|
let res = await this.handleWechatPay(orderData);
|
||||||
|
|
||||||
|
console.log('微信支付成功', res)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 支付成功
|
||||||
|
let orderRes = await this.getOrderInfo()
|
||||||
|
this.currentPage = "pay-result";
|
||||||
|
if (orderRes.status === 2) {
|
||||||
|
this.paySuccess = true;
|
||||||
|
// clearInterval(this.timer)
|
||||||
|
// this.timer = null
|
||||||
|
} else {
|
||||||
|
this.paySuccess = false;
|
||||||
|
}
|
||||||
|
uni.hideLoading()
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error', error)
|
||||||
|
this.currentPage = "pay-result";
|
||||||
|
this.paySuccess = false; // 失败
|
||||||
|
uni.hideLoading()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 查询订单
|
||||||
|
async getOrderInfo() {
|
||||||
|
let res = await request({
|
||||||
|
url: "/api/pay/order",
|
||||||
|
method: "GET",
|
||||||
|
data: {
|
||||||
|
encOrderId: this.encOrderId,
|
||||||
|
outTradeNo: this.outTradeNo
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const data = {
|
||||||
|
...res.data,
|
||||||
|
totalFee: res.data.totalFee / 100,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
// 应用下单
|
||||||
|
async handleOrder(data) {
|
||||||
|
let res = await request({
|
||||||
|
url: "/api/pay/order",
|
||||||
|
method: "POST",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
console.log("handleOrder", res.data);
|
||||||
|
return res.data || {};
|
||||||
|
},
|
||||||
|
|
||||||
|
// 微信支付处理
|
||||||
|
handleWechatPay(payParams) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 在Uniapp中,可以使用uni.requestPayment API
|
||||||
|
uni.requestPayment({
|
||||||
|
provider: "wxpay",
|
||||||
|
timeStamp: payParams.timeStamp,
|
||||||
|
nonceStr: payParams.nonceStr,
|
||||||
|
package: payParams.package,
|
||||||
|
signType: payParams.signType,
|
||||||
|
paySign: payParams.paySign,
|
||||||
|
success: (res) => {
|
||||||
|
console.log("支付成功:", res);
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error("支付失败:", err);
|
||||||
|
reject(new Error("支付失败"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 支付宝支付处理
|
||||||
|
handleAlipay(payParams) {
|
||||||
|
console.log("支付宝支付处理");
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 在Uniapp中,可以使用uni.requestPayment API
|
||||||
|
uni.requestPayment({
|
||||||
|
provider: "alipay",
|
||||||
|
orderInfo: payParams.tradeNO, // 支付宝交易号
|
||||||
|
success: (res) => {
|
||||||
|
if (res.resultCode === "9000") {
|
||||||
|
console.log("支付成功", res);
|
||||||
|
// 建议以后端异步通知或主动查询订单状态为准
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
console.log("支付处理中或失败", res);
|
||||||
|
// 处理其他结果码
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error("支付失败:", err);
|
||||||
|
reject(new Error("支付失败"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async goBackPay() {
|
||||||
|
this.orderInfo = await this.getOrderInfo();
|
||||||
|
this.currentPage = "pay-page";
|
||||||
|
},
|
||||||
|
// 获取URL参数
|
||||||
|
getQuery() {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const currentPage = pages[pages.length - 1];
|
||||||
|
const options = currentPage.options || {};
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
// 判断浏览器环境是微信/支付宝/普通浏览器
|
||||||
|
getBrowserEnv() {
|
||||||
|
// 非H5环境,根据平台判断
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
return "weixin";
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
return "alipay";
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
extractUrlParams(url) {
|
||||||
|
if (!url) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用正则表达式解析URL参数,兼容支付宝环境
|
||||||
|
const params = {};
|
||||||
|
const queryString = url.split("?")[1];
|
||||||
|
|
||||||
|
if (queryString) {
|
||||||
|
const pairs = queryString.split("&");
|
||||||
|
for (let i = 0; i < pairs.length; i++) {
|
||||||
|
const pair = pairs[i].split("=");
|
||||||
|
const key = decodeURIComponent(pair[0]);
|
||||||
|
const value = decodeURIComponent(pair[1] || "");
|
||||||
|
params[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async onShow() {
|
||||||
|
console.log("on Show");
|
||||||
|
// 支付宝
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
|
if (my) {
|
||||||
|
let res = my.getLaunchOptionsSync();
|
||||||
|
console.log("res", res);
|
||||||
|
const qrCode = res.query ? res.query.qrCode : '';
|
||||||
|
let {
|
||||||
|
encOrderId
|
||||||
|
} = this.extractUrlParams(qrCode);
|
||||||
|
if (encOrderId) {
|
||||||
|
this.encOrderId = encOrderId;
|
||||||
|
this.orderInfo = await this.getOrderInfo();
|
||||||
|
}
|
||||||
|
this.getAliUserInfo()
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
async onLoad(options) {
|
||||||
|
console.log("options", options);
|
||||||
|
|
||||||
|
const env = this.getBrowserEnv();
|
||||||
|
console.log('env', env)
|
||||||
|
this.browerEnv = env;
|
||||||
|
if (env === "browser") return;
|
||||||
|
|
||||||
|
// 过滤支付方式,只显示当前环境支持的支付方式
|
||||||
|
this.payMethodList = this.payMethodList.filter((item) => item.id === env);
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if(options.q) { // q: 二维码地址
|
||||||
|
let {
|
||||||
|
encOrderId
|
||||||
|
} = this.extractUrlParams(decodeURIComponent(options.q));
|
||||||
|
console.log('encOrderId', encOrderId)
|
||||||
|
if (encOrderId) {
|
||||||
|
this.encOrderId = encOrderId;
|
||||||
|
this.orderInfo = await this.getOrderInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(options.outTradeNo) {
|
||||||
|
// app进入的
|
||||||
|
this.fromApp = true;
|
||||||
|
this.outTradeNo = options.outTradeNo;
|
||||||
|
this.orderInfo = await this.getOrderInfo();
|
||||||
|
}
|
||||||
|
console.log('encOrderId', this.encOrderId)
|
||||||
|
console.log('outTradeNo', this.outTradeNo)
|
||||||
|
this.getWxUserInfo()
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import url("/static/app.css");
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
body, page {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-name {
|
||||||
|
/* width: 160rpx; */
|
||||||
|
height: 56rpx;
|
||||||
|
margin-top: 140rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #1A1A1A;
|
||||||
|
line-height: 56rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-count {
|
||||||
|
/* width: 250rpx; */
|
||||||
|
height: 92rpx;
|
||||||
|
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 80rpx;
|
||||||
|
color: #FF2C2C;
|
||||||
|
line-height: 72rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
margin: 12rpx 0 16rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company {
|
||||||
|
/* width: 280rpx; */
|
||||||
|
height: 40rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #53896D;
|
||||||
|
line-height: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-methods {
|
||||||
|
margin-top: 80rpx;
|
||||||
|
margin-bottom: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-method-item {
|
||||||
|
width: 640rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0rpx 0rpx 20rpx 0rpx rgba(36, 36, 36, 0.05);
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 0 28rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-method-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-method-item-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-method-name {
|
||||||
|
margin-left: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pay-btn {
|
||||||
|
width: 686rpx;
|
||||||
|
height: 104rpx;
|
||||||
|
border-radius: 1842rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
line-height: 48rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weixin-btn {
|
||||||
|
background: #06BF5E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alipay-btn {
|
||||||
|
background: #2c78fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-result-container {
|
||||||
|
margin-top: 140rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pay-result-text {
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #1A1A1A;
|
||||||
|
line-height: 52rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
margin: 52rpx 0 140rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
width: 312rpx;
|
||||||
|
height: 104rpx;
|
||||||
|
background: #E7E7E7;
|
||||||
|
border-radius: 1842rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #666666;
|
||||||
|
line-height: 48rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.env-err-text {
|
||||||
|
margin-top: 82rpx;
|
||||||
|
width: 504rpx;
|
||||||
|
height: 112rpx;
|
||||||
|
font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #F64F50;
|
||||||
|
line-height: 56rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
|
@ -0,0 +1,13 @@
|
||||||
|
uni.addInterceptor({
|
||||||
|
returnValue (res) {
|
||||||
|
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
res.then((res) => {
|
||||||
|
if (!res) return resolve(res)
|
||||||
|
return res[0] ? reject(res[0]) : resolve(res[1])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$uni-color-primary: #007aff;
|
||||||
|
$uni-color-success: #4cd964;
|
||||||
|
$uni-color-warning: #f0ad4e;
|
||||||
|
$uni-color-error: #dd524d;
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
$uni-text-color:#333;//基本色
|
||||||
|
$uni-text-color-inverse:#fff;//反色
|
||||||
|
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||||
|
$uni-text-color-placeholder: #808080;
|
||||||
|
$uni-text-color-disable:#c0c0c0;
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
$uni-bg-color:#ffffff;
|
||||||
|
$uni-bg-color-grey:#f8f8f8;
|
||||||
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$uni-border-color:#c8c7cc;
|
||||||
|
|
||||||
|
/* 尺寸变量 */
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
$uni-font-size-sm:12px;
|
||||||
|
$uni-font-size-base:14px;
|
||||||
|
$uni-font-size-lg:16px;
|
||||||
|
|
||||||
|
/* 图片尺寸 */
|
||||||
|
$uni-img-size-sm:20px;
|
||||||
|
$uni-img-size-base:26px;
|
||||||
|
$uni-img-size-lg:40px;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$uni-border-radius-sm: 2px;
|
||||||
|
$uni-border-radius-base: 3px;
|
||||||
|
$uni-border-radius-lg: 6px;
|
||||||
|
$uni-border-radius-circle: 50%;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-row-sm: 5px;
|
||||||
|
$uni-spacing-row-base: 10px;
|
||||||
|
$uni-spacing-row-lg: 15px;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$uni-spacing-col-sm: 4px;
|
||||||
|
$uni-spacing-col-base: 8px;
|
||||||
|
$uni-spacing-col-lg: 12px;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
$uni-color-title: #2C405A; // 文章标题颜色
|
||||||
|
$uni-font-size-title:20px;
|
||||||
|
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle:26px;
|
||||||
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph:15px;
|
||||||