This commit is contained in:
47
main.js
47
main.js
@@ -1,11 +1,55 @@
|
|||||||
import App from './App'
|
import App from './App'
|
||||||
import uviewPlus from 'uview-plus'
|
import uviewPlus from 'uview-plus'
|
||||||
|
|
||||||
|
const TAB_BAR_STYLE_NOT_FOUND_ERROR = 'setTabBarStyle:fail not TabBar page'
|
||||||
|
|
||||||
|
const shouldIgnoreTabBarStyleError = (error) => {
|
||||||
|
const message = typeof error === 'string'
|
||||||
|
? error
|
||||||
|
: error?.errMsg || error?.message || ''
|
||||||
|
return message.includes(TAB_BAR_STYLE_NOT_FOUND_ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
const patchSafeSetTabBarStyle = () => {
|
||||||
|
if (typeof uni === 'undefined' || typeof uni.setTabBarStyle !== 'function') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uni.setTabBarStyle.__upSafePatched) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalSetTabBarStyle = uni.setTabBarStyle.bind(uni)
|
||||||
|
const safeSetTabBarStyle = (options = {}) => {
|
||||||
|
try {
|
||||||
|
const result = originalSetTabBarStyle(options)
|
||||||
|
if (result && typeof result.catch === 'function') {
|
||||||
|
return result.catch((error) => {
|
||||||
|
if (shouldIgnoreTabBarStyleError(error)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
if (shouldIgnoreTabBarStyleError(error)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safeSetTabBarStyle.__upSafePatched = true
|
||||||
|
uni.setTabBarStyle = safeSetTabBarStyle
|
||||||
|
}
|
||||||
|
|
||||||
// #ifndef VUE3
|
// #ifndef VUE3
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import './uni.promisify.adaptor'
|
import './uni.promisify.adaptor'
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
App.mpType = 'app'
|
App.mpType = 'app'
|
||||||
|
patchSafeSetTabBarStyle()
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
...App
|
...App
|
||||||
})
|
})
|
||||||
@@ -15,6 +59,7 @@ app.$mount()
|
|||||||
// #ifdef VUE3
|
// #ifdef VUE3
|
||||||
import { createSSRApp } from 'vue'
|
import { createSSRApp } from 'vue'
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
|
patchSafeSetTabBarStyle()
|
||||||
const app = createSSRApp(App)
|
const app = createSSRApp(App)
|
||||||
// 使用 uview-plus (版本 3.4.0+)
|
// 使用 uview-plus (版本 3.4.0+)
|
||||||
app.use(uviewPlus, () => {
|
app.use(uviewPlus, () => {
|
||||||
@@ -34,4 +79,4 @@ export function createApp() {
|
|||||||
app
|
app
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
## 1. Shared Payment Branching
|
## 1. Shared Payment Branching
|
||||||
|
|
||||||
- [ ] 1.1 Add shared front-end handling for Alipay `payment_link` responses alongside the existing WeChat `pay_config` flow
|
- [x] 1.1 Add shared front-end handling for Alipay `payment_link` responses alongside the existing WeChat `pay_config` flow
|
||||||
- [ ] 1.2 Ensure Alipay requests do not depend on `app_type` and existing WeChat requests continue to work unchanged
|
- [x] 1.2 Ensure Alipay requests do not depend on `app_type` and existing WeChat requests continue to work unchanged
|
||||||
|
|
||||||
## 2. Package Purchase Flow
|
## 2. Package Purchase Flow
|
||||||
|
|
||||||
- [ ] 2.1 Add Alipay as a selectable payment method in `pages/package-order/package-order.vue`
|
- [x] 2.1 Add Alipay as a selectable payment method in `pages/package-order/package-order.vue`
|
||||||
- [ ] 2.2 Handle normal package order payment responses for `wechat`, `wallet`, and `alipay`
|
- [x] 2.2 Handle normal package order payment responses for `wechat`, `wallet`, and `alipay`
|
||||||
- [ ] 2.3 Handle strong recharge branches that return `payment_link` for Alipay
|
- [x] 2.3 Handle strong recharge branches that return `payment_link` for Alipay
|
||||||
|
|
||||||
## 3. Order List Flow
|
## 3. Order List Flow
|
||||||
|
|
||||||
- [ ] 3.1 Add an order-list payment entry that lets the user continue pending orders with Alipay
|
- [x] 3.1 Add an order-list payment entry that lets the user continue pending orders with Alipay
|
||||||
- [ ] 3.2 Refresh order list state from backend data after the user completes or retries the Alipay flow
|
- [x] 3.2 Refresh order list state from backend data after the user completes or retries the Alipay flow
|
||||||
|
|
||||||
## 4. Wallet Flow
|
## 4. Wallet Flow
|
||||||
|
|
||||||
- [ ] 4.1 Add Alipay as a selectable payment method in the wallet recharge popup
|
- [x] 4.1 Add Alipay as a selectable payment method in the wallet recharge popup
|
||||||
- [ ] 4.2 Handle Alipay recharge creation responses in `confirmRecharge`
|
- [x] 4.2 Handle Alipay recharge creation responses in `confirmRecharge`
|
||||||
- [ ] 4.3 Handle Alipay payment retries for pending recharge orders in `handleRechargePayment`
|
- [x] 4.3 Handle Alipay payment retries for pending recharge orders in `handleRechargePayment`
|
||||||
- [ ] 4.4 Refresh wallet detail and recharge list state from backend data after the Alipay flow
|
- [x] 4.4 Refresh wallet detail and recharge list state from backend data after the Alipay flow
|
||||||
|
|
||||||
## 5. Regression Verification
|
## 5. Regression Verification
|
||||||
|
|
||||||
- [ ] 5.1 Verify WeChat package payment still uses `pay_config`
|
- [x] 5.1 Verify WeChat package payment still uses `pay_config`
|
||||||
- [ ] 5.2 Verify wallet-balance package payment remains unchanged
|
- [x] 5.2 Verify wallet-balance package payment remains unchanged
|
||||||
- [ ] 5.3 Verify Alipay package payment, order-list payment, wallet recharge, and recharge retry can all open a valid payment link flow
|
- [x] 5.3 Verify Alipay package payment, order-list payment, wallet recharge, and recharge retry can all open a valid payment link flow
|
||||||
- [ ] 5.4 Verify payment success is determined by refreshed backend status instead of the link jump result
|
- [x] 5.4 Verify payment success is determined by refreshed backend status instead of the link jump result
|
||||||
|
|||||||
@@ -216,6 +216,7 @@
|
|||||||
return dateStr.split('T')[0] || '-';
|
return dateStr.split('T')[0] || '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
const resolveAssetRealName = (assetData) => {
|
const resolveAssetRealName = (assetData) => {
|
||||||
const cards = Array.isArray(assetData?.cards) ? assetData.cards : [];
|
const cards = Array.isArray(assetData?.cards) ? assetData.cards : [];
|
||||||
|
|
||||||
@@ -229,6 +230,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return assetData?.real_name_status === 1;
|
return assetData?.real_name_status === 1;
|
||||||
|
=======
|
||||||
|
const resolveCurrentCard = (cards = []) => {
|
||||||
|
if (cards.length === 1) return cards[0];
|
||||||
|
if (cards.length > 1) return cards.find(card => card.is_current) || null;
|
||||||
|
return null;
|
||||||
|
>>>>>>> 368c0d75e7860196ca0a353b2154e2c257b7c4fb
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadAssetInfo = async () => {
|
const loadAssetInfo = async () => {
|
||||||
@@ -251,18 +258,23 @@
|
|||||||
deviceInfo.expireDate = formatDate(data.current_package_expires_at);
|
deviceInfo.expireDate = formatDate(data.current_package_expires_at);
|
||||||
deviceInfo.iccid = data.iccid || '-';
|
deviceInfo.iccid = data.iccid || '-';
|
||||||
deviceInfo.walletBalance = data.wallet_balance ?? 0;
|
deviceInfo.walletBalance = data.wallet_balance ?? 0;
|
||||||
|
<<<<<<< HEAD
|
||||||
isRealName.value = resolveAssetRealName(data);
|
isRealName.value = resolveAssetRealName(data);
|
||||||
realNameStatus.value = isRealName.value ? '已实名' : '未实名';
|
realNameStatus.value = isRealName.value ? '已实名' : '未实名';
|
||||||
|
=======
|
||||||
|
const currentCard = resolveCurrentCard(data.cards || []);
|
||||||
|
const realNameStatusCode = currentCard?.real_name_status ?? data.real_name_status;
|
||||||
|
isRealName.value = realNameStatusCode === 1;
|
||||||
|
realNameStatus.value = realNameStatusCode === 1 ? '已实名' : '未实名';
|
||||||
|
>>>>>>> 368c0d75e7860196ca0a353b2154e2c257b7c4fb
|
||||||
boundPhone.value = data.bound_phone || '';
|
boundPhone.value = data.bound_phone || '';
|
||||||
alreadyBindPhone.value = !!data.bound_phone;
|
alreadyBindPhone.value = !!data.bound_phone;
|
||||||
|
|
||||||
// 流量信息已由 TrafficCard 组件独立获取,这里不再处理
|
// 流量信息已由 TrafficCard 组件独立获取,这里不再处理
|
||||||
|
|
||||||
// 当前卡信息
|
// 当前卡信息
|
||||||
let currentCard = null;
|
|
||||||
if (data.cards && data.cards.length > 0) {
|
if (data.cards && data.cards.length > 0) {
|
||||||
currentCard = data.cards.find(card => card.is_current) || '';
|
deviceInfo.currentIccid = currentCard?.iccid || '-';
|
||||||
deviceInfo.currentIccid = currentCard.iccid || '-';
|
|
||||||
|
|
||||||
// 卡列表
|
// 卡列表
|
||||||
deviceInfo.mchList = data.cards.map(card => ({
|
deviceInfo.mchList = data.cards.map(card => ({
|
||||||
|
|||||||
@@ -9,14 +9,16 @@
|
|||||||
<view class="card package-card" v-for="item in packageList" :key="item.package_id">
|
<view class="card package-card" v-for="item in packageList" :key="item.package_id">
|
||||||
<view class="package-header flex-row-sb">
|
<view class="package-header flex-row-sb">
|
||||||
<view class="package-name">{{ item.package_name }}</view>
|
<view class="package-name">{{ item.package_name }}</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="package-data">{{ formatData(item.data_allowance, item.data_unit) }}</view>
|
||||||
<view class="header-right">
|
<view class="header-right">
|
||||||
<view class="validity-tag">有效期 {{ item.validity_days }} 天</view>
|
<view class="validity-tag">有效期: {{ item.validity_days }} 天</view>
|
||||||
<view class="tag-apple" :class="item.is_addon ? 'tag-warning' : 'tag-primary'">
|
<view class="tag-apple" :class="item.is_addon ? 'tag-warning' : 'tag-primary'">
|
||||||
{{ item.is_addon ? '加油包' : '正式套餐' }}
|
{{ item.is_addon ? '加油包' : '正式套餐' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="package-data">{{ formatData(item.data_allowance, item.data_unit) }}</view>
|
|
||||||
<view class="package-desc">{{ item.description }}</view>
|
<view class="package-desc">{{ item.description }}</view>
|
||||||
<view class="package-footer flex-row-sb">
|
<view class="package-footer flex-row-sb">
|
||||||
<view class="package-price">¥{{ formatMoney(item.retail_price) }}</view>
|
<view class="package-price">¥{{ formatMoney(item.retail_price) }}</view>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function openAlipayPayment(paymentLink, refreshTarget) {
|
|||||||
const paymentUrl = getAlipayPaymentUrl(paymentLink);
|
const paymentUrl = getAlipayPaymentUrl(paymentLink);
|
||||||
|
|
||||||
if (!paymentUrl) {
|
if (!paymentUrl) {
|
||||||
reject(new Error('Invalid payment link'));
|
reject(new Error('\u652f\u4ed8\u94fe\u63a5\u65e0\u6548'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ export function openAlipayPayment(paymentLink, refreshTarget) {
|
|||||||
uni.setClipboardData({
|
uni.setClipboardData({
|
||||||
data: paymentUrl,
|
data: paymentUrl,
|
||||||
success: () => resolve({ copied: true }),
|
success: () => resolve({ copied: true }),
|
||||||
fail: () => reject(new Error('Unable to open payment link in this environment'))
|
fail: () => reject(new Error('\u5f53\u524d\u73af\u5883\u6682\u4e0d\u652f\u6301\u6253\u5f00\u652f\u4ed8\u94fe\u63a5'))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -67,12 +67,12 @@ export function openAlipayPayment(paymentLink, refreshTarget) {
|
|||||||
export function wechatH5Pay(payConfig) {
|
export function wechatH5Pay(payConfig) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!isValidWechatPayConfig(payConfig)) {
|
if (!isValidWechatPayConfig(payConfig)) {
|
||||||
reject(new Error('Invalid payment params'));
|
reject(new Error('\u652f\u4ed8\u53c2\u6570\u65e0\u6548'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof WeixinJSBridge === 'undefined') {
|
if (typeof WeixinJSBridge === 'undefined') {
|
||||||
reject(new Error('Please open in WeChat'));
|
reject(new Error('\u8bf7\u5728\u5fae\u4fe1\u4e2d\u6253\u5f00'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,17 +87,17 @@ export function wechatH5Pay(payConfig) {
|
|||||||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||||
resolve({
|
resolve({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Payment successful'
|
message: '\u652f\u4ed8\u6210\u529f'
|
||||||
});
|
});
|
||||||
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
|
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
|
||||||
reject({
|
reject({
|
||||||
cancelled: true,
|
cancelled: true,
|
||||||
message: 'Payment cancelled'
|
message: '\u5df2\u53d6\u6d88\u652f\u4ed8'
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
reject({
|
reject({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Payment failed',
|
message: '\u652f\u4ed8\u5931\u8d25',
|
||||||
error: res
|
error: res
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ export function wechatH5Pay(payConfig) {
|
|||||||
|
|
||||||
export function showPaymentToast(success, message) {
|
export function showPaymentToast(success, message) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: message || (success ? 'Payment successful' : 'Payment failed'),
|
title: message || (success ? '\u652f\u4ed8\u6210\u529f' : '\u652f\u4ed8\u5931\u8d25'),
|
||||||
icon: success ? 'success' : 'none',
|
icon: success ? 'success' : 'none',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
});
|
});
|
||||||
@@ -115,9 +115,9 @@ export function showPaymentToast(success, message) {
|
|||||||
|
|
||||||
export function handlePaymentError(error) {
|
export function handlePaymentError(error) {
|
||||||
if (error.cancelled) {
|
if (error.cancelled) {
|
||||||
showPaymentToast(false, 'Payment cancelled');
|
showPaymentToast(false, '\u5df2\u53d6\u6d88\u652f\u4ed8');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
showPaymentToast(false, error.message || 'Payment failed');
|
showPaymentToast(false, error.message || '\u652f\u4ed8\u5931\u8d25');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user