fix: 充值体验修复——回调写星尘流水(明细页有记录)+重推幂等+退款回调写流水+充值成功返回我的+我的页onShow刷新余额
This commit is contained in:
@@ -108,7 +108,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||
import { onShow, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { knowledgeApi, aiChatApi, request } from '@/utils/api'
|
||||
@@ -174,9 +174,15 @@ const quotaPercent = computed(() => {
|
||||
onMounted(() => {
|
||||
loadStats()
|
||||
if (userStore.isLoggedIn) {
|
||||
loadVpayInfo()
|
||||
userStore.fetchMe()
|
||||
loadCollected()
|
||||
}
|
||||
})
|
||||
|
||||
// 每次进入/返回本页都刷新余额与额度(充值页支付成功后返回时余额同步)
|
||||
onShow(() => {
|
||||
if (userStore.isLoggedIn) {
|
||||
loadVpayInfo()
|
||||
loadQuota()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -120,8 +120,16 @@ async function recharge() {
|
||||
// #endif
|
||||
|
||||
uni.showToast({ title: '充值成功!', icon: 'success' })
|
||||
// 刷新余额
|
||||
info.value = await request('GET', '/api/vpay/info', null, userStore.token)
|
||||
// 刷新余额后返回"我的"(该页 onShow 会重新拉取余额与额度)
|
||||
try {
|
||||
info.value = await request('GET', '/api/vpay/info', null, userStore.token)
|
||||
} catch (e) {}
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => uni.switchTab({ url: '/pages/profile/profile' }),
|
||||
})
|
||||
}, 1200)
|
||||
} catch (e) {
|
||||
const msg = e.message || '支付未完成'
|
||||
if (msg.includes('cancel')) {
|
||||
|
||||
+49
-26
@@ -48,7 +48,7 @@ module.exports = function registerWxMsgRoutes(app) {
|
||||
const event = fields.Event || fields.event || ''
|
||||
console.log('[wx-msg] 收到推送 Event=' + event, JSON.stringify(fields).slice(0, 500))
|
||||
|
||||
// 代币充值到账:改写用户星尘余额 + 订单状态
|
||||
// 代币充值到账:改写用户星尘余额 + 订单状态 + 写星尘流水(明细页数据源)
|
||||
if (event === 'xpay_coin_pay_notify') {
|
||||
try {
|
||||
const { User, Order, CoinLedger } = require('../models')
|
||||
@@ -61,43 +61,66 @@ module.exports = function registerWxMsgRoutes(app) {
|
||||
)
|
||||
console.log(`[wx-msg] 充值回调解析: order=${outTradeNo} coins=${coins} coinInfo=${JSON.stringify(coinInfo)}`)
|
||||
if (outTradeNo && coins > 0) {
|
||||
// 先查订单,没有也直接给用户加币(Attach 里带了 uid)
|
||||
const order = await Order.findOne({ orderNo: outTradeNo })
|
||||
if (order && order.status === 'pending') {
|
||||
await Order.updateOne({ _id: order._id }, { status: 'paid', paidAt: new Date() })
|
||||
await User.updateOne({ _id: order.userId }, { $inc: { vpayCoins: coins } })
|
||||
console.log(`[wx-msg] ✓ 星尘充值到账(有订单): ${outTradeNo} +${coins} → user=${order.userId}`)
|
||||
// 幂等:微信会重推,同一订单只入账一次(以流水为准)
|
||||
const dup = await CoinLedger.findOne({ orderNo: outTradeNo, type: 'recharge' })
|
||||
if (dup) {
|
||||
console.log(`[wx-msg] 重复推送已忽略: ${outTradeNo}`)
|
||||
} else {
|
||||
// 订单可能未落库或已处理——从 Attach 里拿 uid 直接加
|
||||
try {
|
||||
const attach = typeof coinInfo === 'object' ? coinInfo.Attach || '' : ''
|
||||
const uid = attach ? JSON.parse(attach).uid : ''
|
||||
if (uid) {
|
||||
await User.updateOne({ _id: uid }, { $inc: { vpayCoins: coins } })
|
||||
if (order) await Order.updateOne({ _id: order._id }, { status: 'paid', paidAt: new Date() })
|
||||
console.log(`[wx-msg] ✓ 星尘充值到账(从Attach): ${outTradeNo} +${coins} → user=${uid}`)
|
||||
} else if (order) {
|
||||
await Order.updateOne({ _id: order._id }, { status: 'paid', paidAt: new Date() })
|
||||
await User.updateOne({ _id: order.userId }, { $inc: { vpayCoins: coins } })
|
||||
console.log(`[wx-msg] ✓ 星尘充值到账(订单补偿): ${outTradeNo} +${coins}`)
|
||||
const order = await Order.findOne({ orderNo: outTradeNo })
|
||||
if (order && order.status === 'refunded') {
|
||||
console.log(`[wx-msg] 订单已退款,跳过重复入账: ${outTradeNo}`)
|
||||
} else {
|
||||
// userId 优先取订单,缺失时从 Attach 兜底解析
|
||||
let uid = order ? String(order.userId) : ''
|
||||
if (!uid) {
|
||||
try {
|
||||
const attach = typeof coinInfo === 'object' ? coinInfo.Attach || '' : ''
|
||||
uid = attach ? JSON.parse(attach).uid || '' : ''
|
||||
} catch (e2) { console.error('[wx-msg] Attach解析失败:', e2.message) }
|
||||
}
|
||||
if (uid) {
|
||||
const u = await User.findOneAndUpdate({ _id: uid }, { $inc: { vpayCoins: coins } }, { new: true })
|
||||
if (u) {
|
||||
await CoinLedger.create({
|
||||
openid: u.openid, userId: u._id, type: 'recharge', amount: coins,
|
||||
balanceAfter: u.vpayCoins || 0, description: '星尘充值', orderNo: outTradeNo,
|
||||
})
|
||||
if (order && order.status === 'pending') {
|
||||
await Order.updateOne({ _id: order._id }, { status: 'paid', paidAt: new Date() })
|
||||
}
|
||||
console.log(`[wx-msg] ✓ 星尘充值到账: ${outTradeNo} +${coins} → user=${uid} 余额=${u.vpayCoins}`)
|
||||
}
|
||||
} catch (e2) { console.error('[wx-msg] Attach解析失败:', e2.message) }
|
||||
} else {
|
||||
console.error(`[wx-msg] 充值到账失败: 找不到订单和Attach uid, order=${outTradeNo}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) { console.error('[wx-msg] 充值到账失败:', e.message) }
|
||||
}
|
||||
|
||||
// 退款:扣回星尘
|
||||
// 退款:扣回星尘 + 写流水(仅处理管理后台之外直接发起的退款;后台退款时订单已标 refunded,此处自动跳过)
|
||||
if (event === 'xpay_refund_notify') {
|
||||
try {
|
||||
const { User, Order, CoinLedger } = require('../models')
|
||||
const outTradeNo = fields.OutTradeNo || ''
|
||||
const dup = await CoinLedger.findOne({ orderNo: outTradeNo, type: 'refund' })
|
||||
const order = await Order.findOne({ orderNo: outTradeNo, status: 'paid' })
|
||||
if (order) {
|
||||
await Order.updateOne({ _id: order._id }, { status: 'refunded' })
|
||||
const coins = (order.metadata || {}).coins || 0
|
||||
if (coins > 0) await User.updateOne({ _id: order.userId }, { $inc: { vpayCoins: -coins } })
|
||||
console.log(`[wx-msg] 星尘退款: ${outTradeNo} -${coins}`)
|
||||
if (order && !dup) {
|
||||
const coins = (order.metadata || {}).coins || Math.round((order.amount || 0) * 100) || 0
|
||||
if (coins > 0) {
|
||||
const u = await User.findOneAndUpdate({ _id: order.userId }, { $inc: { vpayCoins: -coins } }, { new: true })
|
||||
await Order.updateOne({ _id: order._id }, { status: 'refunded' })
|
||||
if (u) {
|
||||
await CoinLedger.create({
|
||||
openid: u.openid, userId: u._id, type: 'refund', amount: -coins,
|
||||
balanceAfter: u.vpayCoins || 0, description: '退款扣回', orderNo: outTradeNo,
|
||||
})
|
||||
}
|
||||
console.log(`[wx-msg] 星尘退款: ${outTradeNo} -${coins}`)
|
||||
} else {
|
||||
await Order.updateOne({ _id: order._id }, { status: 'refunded' })
|
||||
}
|
||||
}
|
||||
} catch (e) { console.error('[wx-msg] 退款处理失败:', e.message) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user