支付宝兼容
This commit is contained in:
@@ -176,6 +176,8 @@
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">收货地区</text>
|
||||
<!-- 非支付宝小程序:使用多列 picker -->
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<picker mode="multiSelector" :range="regionColumns" range-key="name" :value="regionIndexes"
|
||||
@change="onRegionChange" @columnchange="onRegionColumnChange">
|
||||
<view class="form-input region-selector">
|
||||
@@ -187,6 +189,19 @@
|
||||
<text class="arrow-icon">›</text>
|
||||
</view>
|
||||
</picker>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 支付宝小程序:使用自定义弹窗 + picker-view -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="form-input region-selector" @click="showRegionPicker = true">
|
||||
<text v-if="addressForm.province && addressForm.city && addressForm.district"
|
||||
class="region-text">
|
||||
{{ addressForm.province }} {{ addressForm.city }} {{ addressForm.district }}
|
||||
</text>
|
||||
<text v-else class="input-placeholder">请选择省市区</text>
|
||||
<text class="arrow-icon">›</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
@@ -254,6 +269,49 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付宝小程序地区选择弹窗 -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="popup-mask" v-if="showRegionPicker" @click="closeRegionPicker">
|
||||
<view class="popup-container" @click.stop>
|
||||
<view class="address-popup">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">选择省市区</text>
|
||||
<view class="close-btn" @click="closeRegionPicker">
|
||||
<text class="close-icon">✕</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-section">
|
||||
<picker-view :value="regionIndexes" @change="onAliRegionChange"
|
||||
indicator-style="height: 50px;">
|
||||
<picker-view-column>
|
||||
<view v-for="item in regionColumns[0]" :key="item.code">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view v-for="item in regionColumns[1]" :key="item.code">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view v-for="item in regionColumns[2]" :key="item.code">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
|
||||
<view class="popup-footer">
|
||||
<view class="confirm-btn" @click="confirmAliRegion">
|
||||
<text>确定</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
@@ -340,6 +398,7 @@
|
||||
const showSkuPopup = ref(false)
|
||||
const showAddressPopup = ref(false)
|
||||
const showAddressDisplay = ref(false) // 地址展示弹窗
|
||||
const showRegionPicker = ref(false) // 支付宝地区选择弹窗
|
||||
|
||||
// 计算是否已有地址
|
||||
const hasAddress = computed(() => {
|
||||
@@ -489,6 +548,45 @@
|
||||
addressForm.value.districtCode = district.code
|
||||
}
|
||||
|
||||
// 支付宝小程序 picker-view 列变化
|
||||
const onAliRegionChange = (e) => {
|
||||
const newVal = e.detail.value || []
|
||||
const oldVal = regionIndexes.value || []
|
||||
|
||||
// 找出发生变化的列
|
||||
let column = -1
|
||||
for (let i = 0; i < newVal.length; i++) {
|
||||
if (newVal[i] !== oldVal[i]) {
|
||||
column = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (column !== -1) {
|
||||
onRegionColumnChange({
|
||||
detail: {
|
||||
column,
|
||||
value: newVal[column]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭支付宝地区弹窗
|
||||
const closeRegionPicker = () => {
|
||||
showRegionPicker.value = false
|
||||
}
|
||||
|
||||
// 支付宝地区选择“确定”
|
||||
const confirmAliRegion = () => {
|
||||
onRegionChange({
|
||||
detail: {
|
||||
value: regionIndexes.value
|
||||
}
|
||||
})
|
||||
closeRegionPicker()
|
||||
}
|
||||
|
||||
// 获取用户收货地址
|
||||
const fetchUserAddress = async () => {
|
||||
try {
|
||||
@@ -767,7 +865,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 创建订单并支付
|
||||
// 创建订单并支付(接入商品多支付平台方案:微信 / 支付宝,小程序端)
|
||||
const createOrder = async () => {
|
||||
try {
|
||||
uni.showLoading({
|
||||
@@ -782,13 +880,24 @@
|
||||
savedAddress.value.receiverAddress :
|
||||
`${addressForm.value.province}${addressForm.value.city}${addressForm.value.district}${addressForm.value.receiverAddress}`
|
||||
|
||||
// 根据当前运行环境确定支付平台
|
||||
let paymentPlatform = 'WECHAT' // 默认微信
|
||||
// #ifdef MP-ALIPAY
|
||||
paymentPlatform = 'ALIPAY'
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// H5 预留 Antom 支付,这里暂时仍按微信处理,如需接入可改为 ANTOM 并补充 paymentType / osType
|
||||
paymentPlatform = 'WECHAT'
|
||||
// #endif
|
||||
|
||||
const orderData = {
|
||||
skuId: selectedSku.value.skuId,
|
||||
quantity:quantity.value,
|
||||
quantity: quantity.value,
|
||||
receiverName: addressData.receiverName,
|
||||
receiverPhone: addressData.receiverPhone,
|
||||
receiverAddress: fullAddress, // 传递完整地址(省市区+详细地址)
|
||||
remark: addressForm.value.remark || ''
|
||||
remark: addressForm.value.remark || '',
|
||||
paymentPlatform // WECHAT / ALIPAY /(预留)ANTOM
|
||||
}
|
||||
|
||||
console.log('创建订单数据:', orderData)
|
||||
@@ -800,11 +909,12 @@
|
||||
if (res && res.code === 200 && res.data) {
|
||||
uni.hideLoading()
|
||||
|
||||
// 调用微信支付
|
||||
// 统一获取平台订单号(商品统一支付订单号)
|
||||
const outOrderNo = res.data.OutOrderNo || res.data.outOrderNo
|
||||
|
||||
// ====================== 微信小程序支付 ======================
|
||||
// #ifdef MP-WEIXIN
|
||||
const payParams = res.data
|
||||
// 保存订单ID,用于取消订单
|
||||
const orderId = payParams.OutOrderNo || res.data.OutOrderNo
|
||||
|
||||
uni.requestPayment({
|
||||
timeStamp: payParams.timeStamp,
|
||||
nonceStr: payParams.nonceStr,
|
||||
@@ -831,26 +941,18 @@
|
||||
},
|
||||
fail: async (payErr) => {
|
||||
console.error('支付失败:', payErr)
|
||||
|
||||
|
||||
// 判断是用户取消还是支付失败
|
||||
if (payErr.errMsg && payErr.errMsg.includes('cancel')) {
|
||||
// 用户取消支付,调用取消订单接口
|
||||
// 用户取消支付,这里预留调用取消订单接口
|
||||
try {
|
||||
// uni.showLoading({
|
||||
// title: '正在取消订单...',
|
||||
// mask: true
|
||||
// })
|
||||
|
||||
// await cancelProductOrder(orderId)
|
||||
|
||||
uni.hideLoading()
|
||||
// await cancelProductOrder(outOrderNo)
|
||||
uni.showToast({
|
||||
title: '支付已取消',
|
||||
icon: 'none'
|
||||
})
|
||||
} catch (cancelError) {
|
||||
console.error('取消订单失败:', cancelError)
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '支付已取消',
|
||||
icon: 'none'
|
||||
@@ -865,6 +967,62 @@
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// ====================== 支付宝小程序支付 ======================
|
||||
// #ifdef MP-ALIPAY
|
||||
console.log(res.data,'支付宝支付参数');
|
||||
|
||||
const tradeNO = res.data.tradeNo
|
||||
if (!tradeNO) {
|
||||
uni.showToast({
|
||||
title: '未获取到支付宝支付参数',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
my.tradePay({
|
||||
tradeNO,
|
||||
success: (payRes) => {
|
||||
console.log('支付宝支付结果:', payRes)
|
||||
if (payRes.resultCode === '9000') {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
|
||||
resetForm()
|
||||
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/subPackages/business/device-orderList'
|
||||
})
|
||||
}, 2000)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '支付失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// ====================== H5 环境(预留 Antom 支付) ======================
|
||||
// #ifdef H5
|
||||
uni.showToast({
|
||||
title: '当前环境暂不支持购买,请使用微信或支付宝小程序',
|
||||
icon: 'none'
|
||||
})
|
||||
// #endif
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
|
||||
@@ -335,25 +335,40 @@
|
||||
navigateToOrderDetail(order);
|
||||
};
|
||||
|
||||
// 立即支付
|
||||
// 立即支付(对齐 device-goods.vue,多平台支付)
|
||||
const handlePayment = async (order) => {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '正在创建支付...',
|
||||
mask: true
|
||||
});
|
||||
console.log(order);
|
||||
|
||||
// 调用后端创建微信支付订单接口(使用订单号)
|
||||
// const res = await createWxPayment(order.orderNo);
|
||||
const res = await createProductOrder({orderNo:order.orderNo});
|
||||
console.log('订单列表立即支付,订单信息:', order);
|
||||
|
||||
// 根据当前运行环境确定支付平台(与 device-goods.vue 保持一致)
|
||||
let paymentPlatform = 'WECHAT'; // 默认微信
|
||||
// #ifdef MP-ALIPAY
|
||||
paymentPlatform = 'ALIPAY';
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// H5 预留 Antom 支付,这里暂时仍按微信处理,如需接入可改为 ANTOM 并补充 paymentType / osType
|
||||
paymentPlatform = 'WECHAT';
|
||||
// #endif
|
||||
|
||||
// 使用商品多支付平台统一下单接口,对已有订单进行支付
|
||||
const res = await createProductOrder({
|
||||
orderNo: order.orderNo,
|
||||
paymentPlatform
|
||||
});
|
||||
|
||||
if (res && res.code === 200 && res.data) {
|
||||
uni.hideLoading();
|
||||
|
||||
|
||||
// 统一获取平台订单号(商品统一支付订单号)
|
||||
const outOrderNo = res.data.OutOrderNo || res.data.outOrderNo;
|
||||
|
||||
// ====================== 微信小程序支付 ======================
|
||||
// #ifdef MP-WEIXIN
|
||||
const payParams = res.data;
|
||||
|
||||
// 调用微信支付
|
||||
uni.requestPayment({
|
||||
timeStamp: payParams.timeStamp,
|
||||
nonceStr: payParams.nonceStr,
|
||||
@@ -367,25 +382,25 @@
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
|
||||
// 刷新订单列表
|
||||
const statusArray = orderStatusTabs[currentTab.value].status;
|
||||
const statusValue = statusArray.length === 0 ? undefined : statusArray[0];
|
||||
await loadOrderList(statusValue);
|
||||
},
|
||||
fail: async (err) => {
|
||||
console.error('支付失败:', err);
|
||||
|
||||
fail: async (payErr) => {
|
||||
console.error('支付失败:', payErr);
|
||||
|
||||
// 判断是用户取消还是支付失败
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
// 用户取消支付,调用取消订单接口
|
||||
if (payErr.errMsg && payErr.errMsg.includes('cancel')) {
|
||||
// 用户取消支付,这里预留调用取消订单接口
|
||||
try {
|
||||
// await cancelProductOrder(order.id || order.orderId);
|
||||
// uni.showToast({
|
||||
// title: '支付已取消',
|
||||
// icon: 'none'
|
||||
// });
|
||||
|
||||
// await cancelProductOrder(outOrderNo || order.orderNo);
|
||||
uni.showToast({
|
||||
title: '支付已取消',
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
// 刷新订单列表
|
||||
const statusArray = orderStatusTabs[currentTab.value].status;
|
||||
const statusValue = statusArray.length === 0 ? undefined : statusArray[0];
|
||||
@@ -406,6 +421,59 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// ====================== 支付宝小程序支付 ======================
|
||||
// #ifdef MP-ALIPAY
|
||||
console.log(res.data, '支付宝支付参数');
|
||||
|
||||
const tradeNO = res.data.tradeNo || res.data.tradeNO;
|
||||
if (!tradeNO) {
|
||||
uni.showToast({
|
||||
title: '未获取到支付宝支付参数',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
my.tradePay({
|
||||
tradeNO,
|
||||
success: async (payRes) => {
|
||||
console.log('支付宝支付结果:', payRes);
|
||||
if (payRes.resultCode === '9000') {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
// 支付成功后刷新订单列表
|
||||
const statusArray = orderStatusTabs[currentTab.value].status;
|
||||
const statusValue = statusArray.length === 0 ? undefined : statusArray[0];
|
||||
await loadOrderList(statusValue);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '支付失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// ====================== H5 环境(预留 Antom 支付) ======================
|
||||
// #ifdef H5
|
||||
uni.showToast({
|
||||
title: '当前环境暂不支持购买,请使用微信或支付宝小程序',
|
||||
icon: 'none'
|
||||
});
|
||||
// #endif
|
||||
} else {
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
|
||||
@@ -176,9 +176,6 @@ import {
|
||||
createCouponPayment,
|
||||
cancelCouponPayment
|
||||
} from '@/config/api/coupon.js'
|
||||
// import {
|
||||
// cancelMemberCardPayment
|
||||
// } from '@/config/api/member.js'
|
||||
import {
|
||||
createMemberCardPayment,
|
||||
getMemberCardsByPosition,
|
||||
@@ -353,7 +350,48 @@ const selectProduct = (product) => {
|
||||
|
||||
const orderNo = ref('')
|
||||
|
||||
// 处理购买
|
||||
// 获取当前支付平台(前端维度)
|
||||
const getPaymentPlatform = () => {
|
||||
// 小程序环境
|
||||
// #ifdef MP-WEIXIN
|
||||
return 'WECHAT'
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
return 'ALIPAY'
|
||||
// #endif
|
||||
// H5 默认使用 ANTOM
|
||||
// #ifdef H5
|
||||
return 'ANTOM'
|
||||
// #endif
|
||||
|
||||
return 'WECHAT'
|
||||
}
|
||||
|
||||
// 支付宝 tradePay 兼容:优先 tradeNO,其次 orderStr
|
||||
const alipayTradePay = ({ tradeNo, orderStr, onSuccess, onFail }) => {
|
||||
// #ifdef MP-ALIPAY
|
||||
const tradeNO = tradeNo
|
||||
if (tradeNO) {
|
||||
my.tradePay({
|
||||
tradeNO,
|
||||
success: onSuccess,
|
||||
fail: onFail
|
||||
})
|
||||
return
|
||||
}
|
||||
if (orderStr) {
|
||||
my.tradePay({
|
||||
orderStr,
|
||||
success: onSuccess,
|
||||
fail: onFail
|
||||
})
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
onFail && onFail(new Error('未获取到支付宝支付参数'))
|
||||
}
|
||||
|
||||
// 处理购买(会员卡 / 优惠券),内部使用商品多支付平台方案下的统一思路
|
||||
const handleBuy = async () => {
|
||||
if (!selectedProduct.value) {
|
||||
uni.showToast({
|
||||
@@ -363,63 +401,89 @@ const handleBuy = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// 会员卡购买
|
||||
const paymentPlatform = getPaymentPlatform()
|
||||
|
||||
// 会员卡购买(按接口文档:POST /app/member/pay)
|
||||
if (currentTab.value === 'card') {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '正在创建订单...'
|
||||
})
|
||||
|
||||
const res = await createMemberCardPayment(selectedProduct.value.id)
|
||||
const res = await createMemberCardPayment(selectedProduct.value.id, paymentPlatform)
|
||||
uni.hideLoading()
|
||||
|
||||
if (res.code === 200 && res.data) {
|
||||
|
||||
orderNo.value = res.data.OutOrderNo;
|
||||
// 调起微信支付
|
||||
uni.requestPayment({
|
||||
timeStamp: res.data.timeStamp,
|
||||
nonceStr: res.data.nonceStr,
|
||||
package: res.data.packageValue || res.data.package,
|
||||
signType: res.data.signType || 'MD5',
|
||||
paySign: res.data.paySign,
|
||||
success: (payRes) => {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 支付成功后,跳转到我的会员卡页面
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/business/my-card'
|
||||
})
|
||||
}, 1500)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付失败:', err)
|
||||
console.log('支付失败详细信息:', err.errMsg.includes('cancel'));
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
if (orderNo.value) {
|
||||
cancelMemberCardPayment(orderNo.value)
|
||||
.then(cancelRes => {
|
||||
console.log('取消支付订单成功:', cancelRes);
|
||||
})
|
||||
.catch(cancelErr => {
|
||||
console.error('取消支付订单失败:', cancelErr);
|
||||
});
|
||||
// 不同平台分别发起支付(字段按文档)
|
||||
// 微信小程序
|
||||
// #ifdef MP-WEIXIN
|
||||
if (paymentPlatform === 'WECHAT') {
|
||||
// 会员卡订单号:OutOrderNo(文档)
|
||||
orderNo.value = res.data.OutOrderNo
|
||||
uni.requestPayment({
|
||||
timeStamp: res.data.timeStamp,
|
||||
nonceStr: res.data.nonceStr,
|
||||
package: res.data.package,
|
||||
signType: res.data.signType || 'MD5',
|
||||
paySign: res.data.paySign,
|
||||
success: () => {
|
||||
uni.showToast({ title: '支付成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: '/subPackages/business/my-card' })
|
||||
}, 1500)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付失败:', err)
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
// 取消支付(本项目取消接口走 device 侧 cancel)
|
||||
orderNo.value && cancelMemberCardPayment(orderNo.value).catch(() => {})
|
||||
uni.showToast({ title: '已取消支付', icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
uni.showToast({
|
||||
title: '已取消支付',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 支付宝小程序
|
||||
// #ifdef MP-ALIPAY
|
||||
if (paymentPlatform === 'ALIPAY') {
|
||||
// 文档返回:tradeNo / outTradeNo;也兼容 orderStr
|
||||
const tradeNo = res.data.tradeNo || res.data.tradeNO
|
||||
const payForm = res.data.payForm || res.data.orderStr
|
||||
alipayTradePay({
|
||||
tradeNo,
|
||||
orderStr: payForm,
|
||||
onSuccess: (payRes) => {
|
||||
if (payRes.resultCode === '9000') {
|
||||
uni.showToast({ title: '支付成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: '/subPackages/business/my-card' })
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
onFail: () => {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
// H5 + Antom(文档里 Antom 预留,当前后端可能返回 cashierUrl / h5Url 之一)
|
||||
// #ifdef H5
|
||||
if (paymentPlatform === 'ANTOM') {
|
||||
const cashierUrl = res.data.cashierUrl || res.data.h5Url
|
||||
if (cashierUrl) {
|
||||
window.location.href = cashierUrl
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '创建订单失败',
|
||||
@@ -437,62 +501,83 @@ const handleBuy = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// 优惠券购买
|
||||
// 优惠券购买(按接口文档:POST /app/coupon/pay)
|
||||
if (currentTab.value === 'coupon') {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '正在创建订单...'
|
||||
})
|
||||
|
||||
const res = await createCouponPayment(selectedProduct.value.couponId)
|
||||
const res = await createCouponPayment(selectedProduct.value.couponId, paymentPlatform)
|
||||
uni.hideLoading()
|
||||
|
||||
if (res.code === 200 && res.data) {
|
||||
// 调起微信支付
|
||||
uni.requestPayment({
|
||||
timeStamp: res.data.timeStamp,
|
||||
nonceStr: res.data.nonceStr,
|
||||
package: res.data.packageValue || res.data.package,
|
||||
signType: res.data.signType || 'MD5',
|
||||
paySign: res.data.paySign,
|
||||
success: (payRes) => {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 支付成功后,跳转到我的优惠券页面
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/business/my-coupon'
|
||||
})
|
||||
}, 1500)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付失败:', err)
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
// 用户取消支付,调用取消接口
|
||||
const orderNo = res.data.OutOrderNo;
|
||||
if (orderNo) {
|
||||
cancelCouponPayment(orderNo)
|
||||
.then(cancelRes => {
|
||||
console.log('取消支付订单成功:', cancelRes);
|
||||
})
|
||||
.catch(cancelErr => {
|
||||
console.error('取消支付订单失败:', cancelErr);
|
||||
});
|
||||
// 微信小程序
|
||||
// #ifdef MP-WEIXIN
|
||||
if (paymentPlatform === 'WECHAT') {
|
||||
uni.requestPayment({
|
||||
timeStamp: res.data.timeStamp,
|
||||
nonceStr: res.data.nonceStr,
|
||||
package: res.data.package,
|
||||
signType: res.data.signType || 'MD5',
|
||||
paySign: res.data.paySign,
|
||||
success: () => {
|
||||
uni.showToast({ title: '支付成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: '/subPackages/business/my-coupon' })
|
||||
}, 1500)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付失败:', err)
|
||||
if (err.errMsg && err.errMsg.includes('cancel')) {
|
||||
const outOrderNo = res.data.OutOrderNo || res.data.outOrderNo
|
||||
outOrderNo && cancelCouponPayment(outOrderNo).catch(() => {})
|
||||
uni.showToast({ title: '已取消支付', icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
uni.showToast({
|
||||
title: '已取消支付',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 支付宝小程序
|
||||
// #ifdef MP-ALIPAY
|
||||
if (paymentPlatform === 'ALIPAY') {
|
||||
const tradeNo = res.data.tradeNo || res.data.tradeNO
|
||||
const payForm = res.data.payForm || res.data.orderStr
|
||||
alipayTradePay({
|
||||
tradeNo,
|
||||
orderStr: payForm,
|
||||
onSuccess: (payRes) => {
|
||||
if (payRes.resultCode === '9000') {
|
||||
uni.showToast({ title: '支付成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: '/subPackages/business/my-coupon' })
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
onFail: () => {
|
||||
uni.showToast({ title: '支付失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
// H5 + Antom
|
||||
// #ifdef H5
|
||||
if (paymentPlatform === 'ANTOM') {
|
||||
const cashierUrl = res.data.cashierUrl || res.data.h5Url
|
||||
if (cashierUrl) {
|
||||
window.location.href = cashierUrl
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.msg || '创建订单失败',
|
||||
|
||||
+183
-51
@@ -78,6 +78,10 @@
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
queryById,
|
||||
createWxPayment,
|
||||
getWxPaymentStatus,
|
||||
createAliPayment,
|
||||
getAliPaymentStatus,
|
||||
createAntomPayment,
|
||||
getAntomPaymentMethods,
|
||||
getAntomPaymentStatus
|
||||
@@ -107,9 +111,9 @@
|
||||
const countdown = ref(15 * 60) // 15分钟 = 900秒
|
||||
let countdownTimer = null
|
||||
|
||||
// 支付方式相关
|
||||
// 支付方式相关(微信/支付宝/H5-Antom 多平台)
|
||||
const paymentMethods = ref([])
|
||||
const selectedPaymentMethod = ref('ALIPAY') // 默认选择支付宝
|
||||
const selectedPaymentMethod = ref('WECHAT') // 默认微信
|
||||
|
||||
// 地点名称(可以从设备信息中获取,这里先用默认值)
|
||||
const locationName = ref('澎创办公室')
|
||||
@@ -197,11 +201,11 @@
|
||||
deviceNo.value = orderData.deviceNo;
|
||||
await loadDeviceInfo();
|
||||
await loadPaymentMethods();
|
||||
// #ifdef H5
|
||||
// 如果订单状态是等待支付,启动相应的支付状态轮询
|
||||
if(orderInfo.value.orderStatus=='waiting_for_payment'){
|
||||
// 使用当前选中的支付方式类型进行轮询
|
||||
startPaymentStatusPolling();
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
throw new Error(t('order.getOrderFailed'))
|
||||
}
|
||||
@@ -253,35 +257,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 加载支付方式列表
|
||||
// 加载支付方式列表(根据平台决定可选项)
|
||||
const loadPaymentMethods = async () => {
|
||||
if (!orderInfo.value.orderNo) return;
|
||||
const methods = []
|
||||
|
||||
try {
|
||||
const osType = getOsType();
|
||||
console.log('当前系统类型:', osType);
|
||||
// 小程序环境下:微信 / 支付宝
|
||||
// #ifdef MP-WEIXIN
|
||||
methods.push({ paymentMethodType: 'WECHAT', paymentMethodName: '微信支付' })
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
methods.push({ paymentMethodType: 'ALIPAY', paymentMethodName: '支付宝支付' })
|
||||
// #endif
|
||||
|
||||
const res = await getAntomPaymentMethods(orderInfo.value.orderNo, osType);
|
||||
if (res.code === 200 && res.data && res.data.paymentOptions) {
|
||||
paymentMethods.value = res.data.paymentOptions;
|
||||
console.log('支付方式列表:', paymentMethods.value);
|
||||
// 如果有支付方式,默认选择第一个
|
||||
if (paymentMethods.value.length > 0) {
|
||||
selectedPaymentMethod.value = paymentMethods.value[0].paymentMethodType;
|
||||
// H5 环境:使用 Antom 聚合支付(多通道)
|
||||
// #ifdef H5
|
||||
if (orderInfo.value.orderNo) {
|
||||
try {
|
||||
const osType = getOsType();
|
||||
const res = await getAntomPaymentMethods(orderInfo.value.orderNo, osType);
|
||||
if (res.code === 200 && res.data && res.data.paymentOptions) {
|
||||
res.data.paymentOptions.forEach(item => {
|
||||
methods.push({
|
||||
paymentMethodType: item.paymentMethodType,
|
||||
paymentMethodName: item.paymentMethodName || item.paymentMethodType
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取 Antom 支付方式失败:', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取支付方式失败:', error);
|
||||
// 如果获取失败,使用默认支付方式
|
||||
paymentMethods.value = [{
|
||||
paymentMethodType: 'ALIPAY',
|
||||
paymentMethodName: '支付宝'
|
||||
},
|
||||
{
|
||||
paymentMethodType: 'WECHATPAY',
|
||||
paymentMethodName: '微信支付'
|
||||
}
|
||||
];
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 兜底:至少保留一个微信
|
||||
if (!methods.length) {
|
||||
methods.push({ paymentMethodType: 'WECHAT', paymentMethodName: '微信支付' })
|
||||
}
|
||||
|
||||
paymentMethods.value = methods
|
||||
if (paymentMethods.value.length > 0) {
|
||||
selectedPaymentMethod.value = paymentMethods.value[0].paymentMethodType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,8 +330,85 @@
|
||||
title: t('common.processing')
|
||||
})
|
||||
|
||||
const method = selectedPaymentMethod.value
|
||||
|
||||
// 微信小程序支付押金
|
||||
// #ifdef MP-WEIXIN
|
||||
if (method === 'WECHAT') {
|
||||
const wxRes = await createWxPayment(orderInfo.value.orderNo)
|
||||
if (wxRes.code === 200 && wxRes.data) {
|
||||
const payData = wxRes.data
|
||||
await new Promise((resolve, reject) => {
|
||||
wx.requestPayment({
|
||||
...payData,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
// 支付成功后轮询微信支付状态
|
||||
startPaymentStatusPolling('WECHAT')
|
||||
return
|
||||
} else {
|
||||
throw new Error(wxRes.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 支付宝小程序支付押金
|
||||
// #ifdef MP-ALIPAY
|
||||
if (method === 'ALIPAY') {
|
||||
const aliRes = await createAliPayment(orderInfo.value.orderNo)
|
||||
if (aliRes.code === 200 && aliRes.data) {
|
||||
// 后端当前实际返回结构示例:
|
||||
// { code:200, msg:'操作成功', data:{ tradeNo:'xxx', outTradeNo:'yyy' } }
|
||||
const tradeNO = aliRes.data.tradeNo || aliRes.data.outTradeNo
|
||||
const payForm = aliRes.data.payForm || aliRes.data.orderStr
|
||||
|
||||
if (!tradeNO && !payForm) {
|
||||
throw new Error('未获取到支付宝支付参数')
|
||||
}
|
||||
|
||||
// 优先使用 tradeNO 方式,其次兼容老的 orderStr 方式
|
||||
if (tradeNO) {
|
||||
my.tradePay({
|
||||
tradeNO,
|
||||
success: (res) => {
|
||||
if (res.resultCode === '9000') {
|
||||
startPaymentStatusPolling('ALIPAY')
|
||||
} else {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
my.tradePay({
|
||||
orderStr: payForm,
|
||||
success: (res) => {
|
||||
if (res.resultCode === '9000') {
|
||||
startPaymentStatusPolling('ALIPAY')
|
||||
} else {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
} else {
|
||||
throw new Error(aliRes.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// H5 + Antom 聚合支付
|
||||
// #ifdef H5
|
||||
const osType = getOsType();
|
||||
const res = await createAntomPayment(orderInfo.value.orderNo, selectedPaymentMethod.value, osType)
|
||||
const res = await createAntomPayment(orderInfo.value.orderNo, method, osType)
|
||||
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const paymentUrl = res.data.h5Url;
|
||||
@@ -326,21 +418,16 @@
|
||||
}
|
||||
|
||||
uni.hideLoading();
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('pendingPaymentNo', orderId.value);
|
||||
// 跳转到支付页面
|
||||
// uni.navigateTo({
|
||||
// url: `/pages/webview/index?url=${encodeURIComponent(paymentUrl)}&title=支付`
|
||||
// });
|
||||
window.open(paymentUrl);
|
||||
// #endif
|
||||
|
||||
// 开始轮询支付状态
|
||||
startPaymentStatusPolling();
|
||||
|
||||
// 开始轮询支付状态(传入当前选中的支付方式类型)
|
||||
startPaymentStatusPolling(method);
|
||||
return
|
||||
} else {
|
||||
throw new Error(res?.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.error('支付失败:', error)
|
||||
uni.showToast({
|
||||
@@ -352,14 +439,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 轮询支付状态
|
||||
// 轮询定时器
|
||||
let pollingTimer = null;
|
||||
const startPaymentStatusPolling = () => {
|
||||
|
||||
/**
|
||||
* 统一的支付状态轮询方法
|
||||
* @param {string} paymentMethodType - 支付方式类型,如 'WECHAT' | 'ALIPAY' | 'WECHATPAY' 等,与 selectedPaymentMethod 保持一致
|
||||
*/
|
||||
const startPaymentStatusPolling = (paymentMethodType = null) => {
|
||||
// 清除之前的定时器
|
||||
if (pollingTimer) {
|
||||
clearInterval(pollingTimer);
|
||||
}
|
||||
|
||||
// 如果没有传入支付方式类型,使用当前选中的支付方式
|
||||
const methodType = paymentMethodType || selectedPaymentMethod.value;
|
||||
|
||||
let pollCount = 0;
|
||||
const maxPollCount = 60; // 最多轮询60次(5分钟)
|
||||
|
||||
@@ -376,32 +471,64 @@
|
||||
}
|
||||
|
||||
try {
|
||||
let res;
|
||||
let status, successStatus, failStatuses;
|
||||
|
||||
// #ifdef H5
|
||||
// H5 环境统一使用 Antom 聚合支付 API
|
||||
const osType = getOsType();
|
||||
const res = await getAntomPaymentStatus(orderInfo.value.orderNo, osType);
|
||||
res = await getAntomPaymentStatus(orderInfo.value.orderNo, osType);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const paymentStatus = res.data.paymentStatus;
|
||||
status = res.data.paymentStatus;
|
||||
successStatus = 'SUCCESS';
|
||||
failStatuses = ['FAIL', 'CANCELLED'];
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序:根据支付方式类型判断
|
||||
if (methodType === 'WECHAT' || methodType === 'WECHATPAY') {
|
||||
res = await getWxPaymentStatus(orderInfo.value.orderNo);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
status = res.data.tradeStatus;
|
||||
successStatus = 'SUCCESS';
|
||||
failStatuses = ['FAIL', 'CANCELLED'];
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
// 支付宝小程序
|
||||
if (methodType === 'ALIPAY') {
|
||||
res = await getAliPaymentStatus(orderInfo.value.orderNo);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
status = res.data.tradeStatus;
|
||||
successStatus = 'TRADE_SUCCESS';
|
||||
failStatuses = ['TRADE_FAIL', 'TRADE_CANCELLED'];
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (paymentStatus === 'SUCCESS') {
|
||||
// 处理支付状态结果
|
||||
if (res && res.code === 200 && res.data && status) {
|
||||
// 支付成功
|
||||
if (status === successStatus) {
|
||||
clearInterval(pollingTimer);
|
||||
|
||||
// uni.showToast({
|
||||
// title: t('payment.paymentSuccess'),
|
||||
// icon: 'success'
|
||||
// });
|
||||
|
||||
try {
|
||||
await updateUserBalance(orderId.value);
|
||||
} catch (error) {
|
||||
console.warn('更新用户余额失败:', error);
|
||||
}
|
||||
console.log(orderInfo);
|
||||
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: `/pages/order/success?orderId=${orderId.value}&deviceId=${orderInfo.value.deviceNo}`
|
||||
});
|
||||
}, 1500);
|
||||
} else if (paymentStatus === 'FAIL' || paymentStatus === 'CANCELLED') {
|
||||
}
|
||||
// 支付失败
|
||||
else if (failStatuses && failStatuses.includes(status)) {
|
||||
clearInterval(pollingTimer);
|
||||
uni.showToast({
|
||||
title: '支付失败,请重新支付',
|
||||
@@ -410,11 +537,16 @@
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询支付状态失败:', error);
|
||||
const errorMsg = methodType === 'ALIPAY' ? '支付宝' : (methodType === 'WECHAT' || methodType === 'WECHATPAY') ? '微信' : '支付';
|
||||
console.error(`查询${errorMsg}支付状态失败:`, error);
|
||||
}
|
||||
}, 5000); // 每5秒查询一次
|
||||
}
|
||||
|
||||
// 兼容性方法:保持原有函数名,内部调用统一方法
|
||||
const startWxPaymentStatusPolling = () => startPaymentStatusPolling('WECHAT');
|
||||
const startAliPaymentStatusPolling = () => startPaymentStatusPolling('ALIPAY');
|
||||
|
||||
// 更新导航栏倒计时
|
||||
const updateNavBarCountdown = () => {
|
||||
const minutes = Math.floor(countdown.value / 60).toString().padStart(2, '0')
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
// 跳转到投诉记录列表
|
||||
const navigateToRecord = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/feedback/list'
|
||||
url: '/subPackages/service/feedback/list'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
// 跳转到详情页
|
||||
const navigateToDetail = (item) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/feedback/detail?id=${item.id || item.feedbackId}`
|
||||
url: `/subPackages/service/feedback/detail?id=${item.id || item.feedbackId}`
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
<view class="help-container">
|
||||
<!-- 常见问题 -->
|
||||
<view class="faq-section">
|
||||
<uv-collapse :border="false">
|
||||
<uv-collapse-item
|
||||
v-for="(item, index) in faqList"
|
||||
:key="index"
|
||||
:title="$t(item.question)"
|
||||
:name="index"
|
||||
<view
|
||||
v-for="(item, index) in faqList"
|
||||
:key="index"
|
||||
class="collapse-item"
|
||||
>
|
||||
<view
|
||||
class="collapse-header"
|
||||
@click="toggleCollapse(index)"
|
||||
>
|
||||
<text class="collapse-title">{{ $t(item.question) }}</text>
|
||||
<text class="collapse-icon" :class="{ 'active': activeIndex === index }">▼</text>
|
||||
</view>
|
||||
<view
|
||||
class="collapse-content"
|
||||
:class="{ 'show': activeIndex === index }"
|
||||
>
|
||||
<view class="answer-content">
|
||||
<text class="answer-text">{{ $t(item.answer) }}</text>
|
||||
</view>
|
||||
</uv-collapse-item>
|
||||
</uv-collapse>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系客服 -->
|
||||
@@ -34,7 +43,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { HELP_CONTENT } from '@/constants/help'
|
||||
import { getCustomerPhone } from '@/util/index.js'
|
||||
@@ -44,6 +53,7 @@ const { t } = useI18n()
|
||||
|
||||
const faqList = ref(HELP_CONTENT.FAQ_LIST)
|
||||
const customerPhone = ref(HELP_CONTENT.CONTACT.PHONE.VALUE)
|
||||
const activeIndex = ref(null)
|
||||
|
||||
onLoad(() => {
|
||||
uni.setNavigationBarTitle({
|
||||
@@ -52,6 +62,14 @@ onLoad(() => {
|
||||
customerPhone.value = getCustomerPhone()
|
||||
})
|
||||
|
||||
const toggleCollapse = (index) => {
|
||||
if (activeIndex.value === index) {
|
||||
activeIndex.value = null
|
||||
} else {
|
||||
activeIndex.value = index
|
||||
}
|
||||
}
|
||||
|
||||
const makePhoneCall = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: customerPhone.value
|
||||
@@ -72,15 +90,67 @@ const makePhoneCall = () => {
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
overflow: hidden;
|
||||
|
||||
.answer-content {
|
||||
padding: 20rpx 30rpx 30rpx;
|
||||
background: #f9f9f9;
|
||||
.collapse-item {
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
.answer-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
display: block;
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.collapse-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:active {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.collapse-title {
|
||||
flex: 1;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.collapse-icon {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
transition: transform 0.3s;
|
||||
transform: rotate(0deg);
|
||||
|
||||
&.active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-content {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease-out;
|
||||
|
||||
&.show {
|
||||
max-height: 2000rpx;
|
||||
transition: max-height 0.3s ease-in;
|
||||
}
|
||||
|
||||
.answer-content {
|
||||
padding: 20rpx 30rpx 30rpx;
|
||||
background: #f9f9f9;
|
||||
|
||||
.answer-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,27 @@
|
||||
<view class="title">{{ $t('auth.loginTitle') }}</view>
|
||||
<view class="subtitle">{{ $t('auth.loginDesc') }}</view>
|
||||
|
||||
<!-- 微信一键手机号快捷登录(推荐) -->
|
||||
<!-- 微信小程序:一键手机号快捷登录 -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button v-if="!isAgreed" class="btn primary" @click="handleLoginClick">
|
||||
{{ $t('auth.getPhoneNumber') }}
|
||||
</button>
|
||||
<button v-else class="btn primary" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber">
|
||||
{{ $t('auth.getPhoneNumber') }}
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 支付宝小程序:授权码快捷登录(不支持 open-type=getPhoneNumber) -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<button v-if="!isAgreed" class="btn primary" @click="handleLoginClick">
|
||||
{{ $t('auth.loginBtn') }}
|
||||
</button>
|
||||
<button v-else class="btn primary" @click="onAlipayLogin">
|
||||
{{ $t('auth.loginBtn') }}
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- H5:不显示小程序快捷登录按钮 -->
|
||||
|
||||
<!-- 手机号验证码登录 -->
|
||||
<button class="btn outline" @click="goToPhoneLogin" v-if="isHTML5">
|
||||
@@ -40,7 +54,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { wxLogin, getUserPhoneNumber, getUserInfo } from '@/util/index.js'
|
||||
import { wxLogin, alipayLogin, getUserPhoneNumber, getUserInfo } from '@/util/index.js'
|
||||
import { useI18n } from '@/utils/i18n.js'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -116,13 +130,12 @@
|
||||
uni.reLaunch({ url: target })
|
||||
}
|
||||
|
||||
// 微信快捷登录入口(备用,目前主流程使用一键手机号登录)
|
||||
const onWeChatLogin = async () => {
|
||||
try {
|
||||
// 先检查是否同意协议
|
||||
await checkAgreement()
|
||||
|
||||
await wxLogin()
|
||||
uni.showToast({ title: t('auth.loginSuccess'), icon: 'success' })
|
||||
await wxLogin()
|
||||
uni.showToast({ title: t('auth.loginSuccess'), icon: 'success' })
|
||||
await navigateAfterLogin()
|
||||
} catch (error) {
|
||||
if (error.message !== t('auth.pleaseAgreeToTerms')) {
|
||||
@@ -131,6 +144,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 支付宝快捷登录入口(支付宝小程序)
|
||||
const onAlipayLogin = async () => {
|
||||
try {
|
||||
await checkAgreement()
|
||||
await alipayLogin()
|
||||
uni.showToast({ title: t('auth.loginSuccess'), icon: 'success' })
|
||||
await navigateAfterLogin()
|
||||
} catch (error) {
|
||||
if (error.message !== t('auth.pleaseAgreeToTerms')) {
|
||||
uni.showToast({ title: error.message || t('auth.loginFailed'), icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:手机号一致性校验不在登录页做;扫码/租借前校验(支付宝 my.getPhoneNumber)
|
||||
|
||||
const onGetPhoneNumber = async (e) => {
|
||||
if (!e || e.detail.errMsg !== 'getPhoneNumber:ok') {
|
||||
uni.showToast({ title: t('auth.phoneCancelled'), icon: 'none' })
|
||||
@@ -138,9 +167,9 @@
|
||||
}
|
||||
|
||||
try {
|
||||
// 先微信登录,获取 token
|
||||
// 先完成微信登录(/app/user/quickLogin,后端建立/查询 WECHAT_MINI 用户)
|
||||
await wxLogin()
|
||||
// 再用微信返回的临时 code 换取手机号
|
||||
// 再用微信返回的临时 code 换取手机号(后端按文档更新 phone 字段)
|
||||
await getUserPhoneNumber(e.detail.code)
|
||||
uni.showToast({ title: t('auth.loginSuccess'), icon: 'success' })
|
||||
await navigateAfterLogin()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="my-page">
|
||||
<view class="user-card" @click="navigateTo('/pages/userProfile/index')">
|
||||
<view class="user-card" @click="navigateTo('/subPackages/user/userProfile/index')">
|
||||
<view class="avatar-box">
|
||||
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" lazy-load="true"></image>
|
||||
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill" lazy-load="true"></image>
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
</view>
|
||||
<view class="group">
|
||||
<view class="item" @click="navigateTo('/subPackages/other/legal/agreement')">
|
||||
<text class="label">{{ $t('user.userAgreement') }}</text>
|
||||
<text class="label">{{ $t('user.settinguserAgreement') }}</text>
|
||||
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
|
||||
</view>
|
||||
<view class="item" @click="navigateTo('/subPackages/other/legal/privacy')">
|
||||
<text class="label">{{ $t('user.privacyPolicy') }}</text>
|
||||
<text class="label">{{ $t('user.settinguserprivacyPolicy') }}</text>
|
||||
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
|
||||
</view>
|
||||
<view class="item" @click="navigateTo('/subPackages/other/legal/terms')">
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<!-- <button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button> -->
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="avatar-tip">{{ $t('userProfile.clickToChange') }}</view>
|
||||
</view>
|
||||
@@ -129,6 +132,8 @@ const redirectToLogin = () => {
|
||||
|
||||
// 小程序原生选择头像回调
|
||||
const onChooseAvatar = async (e) => {
|
||||
console.log(e.detail.avatarUrl,'获取头像详情');
|
||||
|
||||
try {
|
||||
const token = uni.getStorageSync('token');
|
||||
if (!token) {
|
||||
@@ -282,7 +287,7 @@ function maskPhone(phone) {
|
||||
}
|
||||
|
||||
/* 仅小程序端存在,此按钮覆盖在头像上捕获点击以触发选择头像 */
|
||||
/* #ifdef MP-WEIXIN */
|
||||
/* #ifdef MP-WEIXIN || MP-ALIPAY */
|
||||
.avatar-choose-btn {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
Reference in New Issue
Block a user