Browse Source

fix(account): track pending SIM recharge orders per card

Keep one unpaid/processing banner entry per sim card so creating a
second pending order no longer hides earlier pay/cancel actions.
main
xiaosi 3 weeks ago
parent
commit
75a78a9893
  1. 93
      src/views/AccountView/AccountView.vue

93
src/views/AccountView/AccountView.vue

@ -142,30 +142,31 @@
</t-table> </t-table>
<div class="table-footer" v-if="simTotal"><t-pagination v-model:current="simPageNum" :total="simTotal" :page-size="10" @current-change="loadSim" /></div> <div class="table-footer" v-if="simTotal"><t-pagination v-model:current="simPageNum" :total="simTotal" :page-size="10" @current-change="loadSim" /></div>
<div <div
v-if="pendingSimOrder && isPendingSimOrderActionable"
v-for="order in actionablePendingSimOrders"
:key="order.id"
class="pending-sim-order" class="pending-sim-order"
> >
<div> <div>
<strong>待支付通信卡充值</strong> <strong>待支付通信卡充值</strong>
<small> <small>
{{ cardLabel(pendingSimOrder.simCardId) }}
· {{ pendingSimOrder.amountGb != null ? `${pendingSimOrder.amountGb} GB` : '--' }}
· {{ moneyFromFen(pendingSimOrder.totalFeeFen) }}
· {{ payStatusName(pendingSimOrder.paymentStatus) }}
{{ cardLabel(order.simCardId) }}
· {{ order.amountGb != null ? `${order.amountGb} GB` : '--' }}
· {{ moneyFromFen(order.totalFeeFen) }}
· {{ payStatusName(order.paymentStatus) }}
</small> </small>
</div> </div>
<div class="account-card-actions" style="margin-top:0"> <div class="account-card-actions" style="margin-top:0">
<t-button <t-button
variant="text" variant="text"
theme="primary" theme="primary"
:loading="payingPendingSim"
@click="payPendingSimOrder"
:loading="payingPendingSimId === order.id"
@click="payPendingSimOrder(order)"
>去支付</t-button> >去支付</t-button>
<t-button <t-button
variant="text" variant="text"
theme="danger" theme="danger"
:loading="cancellingPendingSim"
@click="cancelPendingSimOrder"
:loading="cancellingPendingSimId === order.id"
@click="cancelPendingSimOrder(order)"
>取消</t-button> >取消</t-button>
</div> </div>
</div> </div>
@ -326,9 +327,9 @@ const simRechargeOpen = ref(false)
const simRechargeCard = ref(null) const simRechargeCard = ref(null)
const selectedSimPackageId = ref(0) const selectedSimPackageId = ref(0)
const simRecharging = ref(false) const simRecharging = ref(false)
const pendingSimOrder = ref(null)
const payingPendingSim = ref(false)
const cancellingPendingSim = ref(false)
const pendingSimOrdersByCard = ref({})
const payingPendingSimId = ref(0)
const cancellingPendingSimId = ref(0)
const editOpen = ref(false); const saving = ref(false); const editForm = ref({ name: '', email: '' }) const editOpen = ref(false); const saving = ref(false); const editForm = ref({ name: '', email: '' })
const orderColumns = [ const orderColumns = [
@ -397,10 +398,8 @@ const profileInitial = computed(() => profileName.value === '--' ? '-' : profile
const invoiceOrderOptions = computed(() => [{ label: '请选择已支付订单', value: 0 }, ...invoiceOrders.value.map((order) => ({ label: `${order.id} · ${money(order.totalPrice)}`, value: order.id }))]) const invoiceOrderOptions = computed(() => [{ label: '请选择已支付订单', value: 0 }, ...invoiceOrders.value.map((order) => ({ label: `${order.id} · ${money(order.totalPrice)}`, value: order.id }))])
const activeSimCount = computed(() => simCards.value.filter((card) => simStatus(card).cls === 'normal').length) const activeSimCount = computed(() => simCards.value.filter((card) => simStatus(card).cls === 'normal').length)
const warnSimCount = computed(() => simTotal.value - activeSimCount.value) const warnSimCount = computed(() => simTotal.value - activeSimCount.value)
const isPendingSimOrderActionable = computed(() => {
const status = pendingSimOrder.value?.paymentStatus
return status === 'unpaid' || status === 'processing'
})
const actionablePendingSimOrders = computed(() => Object.values(pendingSimOrdersByCard.value || {}).filter((order) => order?.paymentStatus === 'unpaid' || order?.paymentStatus === 'processing'))
function applyPage(targetRef, page) { function applyPage(targetRef, page) {
const records = page?.records || [] const records = page?.records || []
@ -556,52 +555,67 @@ function mapPendingSimOrder(order) {
paymentStatus: order.paymentStatus || order.payStatus || 'unpaid' paymentStatus: order.paymentStatus || order.payStatus || 'unpaid'
} }
} }
function clearPendingSimOrderIfSettled(status) {
if (status === 'paid' || status === 'cancelled' || status === 'closed') {
pendingSimOrder.value = null
function upsertPendingSimOrder(order) {
const mapped = mapPendingSimOrder(order)
if (!mapped?.simCardId) return null
const next = { ...pendingSimOrdersByCard.value }
if (mapped.paymentStatus === 'paid' || mapped.paymentStatus === 'cancelled' || mapped.paymentStatus === 'closed') {
delete next[String(mapped.simCardId)]
} else {
next[String(mapped.simCardId)] = mapped
}
pendingSimOrdersByCard.value = next
return mapped
}
function removePendingSimOrder(simCardId) {
if (simCardId == null) return
const next = { ...pendingSimOrdersByCard.value }
delete next[String(simCardId)]
pendingSimOrdersByCard.value = next
} }
function findPendingSimOrderForCard(simCardId) {
if (simCardId == null) return null
return pendingSimOrdersByCard.value[String(simCardId)] || null
} }
async function refreshPendingSimOrder(orderId) { async function refreshPendingSimOrder(orderId) {
if (!orderId) return if (!orderId) return
try { try {
const order = await request.get(urls.SIM_RECHARGE_ORDER(orderId)) const order = await request.get(urls.SIM_RECHARGE_ORDER(orderId))
const mapped = mapPendingSimOrder(order)
pendingSimOrder.value = mapped
clearPendingSimOrderIfSettled(mapped?.paymentStatus)
upsertPendingSimOrder(order)
} catch { } catch {
// keep local pending if refresh fails // keep local pending if refresh fails
} }
} }
async function payPendingSimOrder() {
if (!pendingSimOrder.value?.id || !isPendingSimOrderActionable.value) return
payingPendingSim.value = true
async function payPendingSimOrder(order) {
if (!order?.id || !(order.paymentStatus === 'unpaid' || order.paymentStatus === 'processing')) return
payingPendingSimId.value = order.id
try { try {
const payment = await createPayment('sim_recharge_order', pendingSimOrder.value.id)
const payment = await createPayment('sim_recharge_order', order.id)
ui.toast(describePayment(payment)) ui.toast(describePayment(payment))
await refreshPendingSimOrder(pendingSimOrder.value.id)
await refreshPendingSimOrder(order.id, order.simCardId)
await loadSim() await loadSim()
} catch (error) { } catch (error) {
ui.toast(error.message || '发起支付失败') ui.toast(error.message || '发起支付失败')
await refreshPendingSimOrder(pendingSimOrder.value?.id)
await refreshPendingSimOrder(order.id, order.simCardId)
} finally { } finally {
payingPendingSim.value = false
payingPendingSimId.value = 0
} }
} }
async function cancelPendingSimOrder() {
if (!pendingSimOrder.value?.id || !isPendingSimOrderActionable.value) return
async function cancelPendingSimOrder(order) {
if (!order?.id || !(order.paymentStatus === 'unpaid' || order.paymentStatus === 'processing')) return
const ok = await ui.confirm('取消该通信卡充值订单?', '仅待支付/支付中订单可取消。', ['订单将关闭', '可重新选择套餐充值']) const ok = await ui.confirm('取消该通信卡充值订单?', '仅待支付/支付中订单可取消。', ['订单将关闭', '可重新选择套餐充值'])
if (!ok) return if (!ok) return
cancellingPendingSim.value = true
cancellingPendingSimId.value = order.id
try { try {
await request.delete(urls.SIM_RECHARGE_ORDER(pendingSimOrder.value.id))
pendingSimOrder.value = null
await request.delete(urls.SIM_RECHARGE_ORDER(order.id))
removePendingSimOrder(order.simCardId)
ui.toast('充值订单已取消') ui.toast('充值订单已取消')
await loadSim() await loadSim()
} catch (error) { } catch (error) {
ui.toast(error.message || '取消失败') ui.toast(error.message || '取消失败')
await refreshPendingSimOrder(pendingSimOrder.value?.id)
await refreshPendingSimOrder(order.id, order.simCardId)
} finally { } finally {
cancellingPendingSim.value = false
cancellingPendingSimId.value = 0
} }
} }
async function submitSimRecharge() { async function submitSimRecharge() {
@ -618,15 +632,16 @@ async function submitSimRecharge() {
{ packageId: Number(selectedSimPackageId.value) } { packageId: Number(selectedSimPackageId.value) }
) )
orderCreated = true orderCreated = true
pendingSimOrder.value = mapPendingSimOrder(order)
upsertPendingSimOrder(order)
const payment = await createPayment('sim_recharge_order', order.id) const payment = await createPayment('sim_recharge_order', order.id)
ui.toast(describePayment(payment)) ui.toast(describePayment(payment))
simRechargeOpen.value = false simRechargeOpen.value = false
await refreshPendingSimOrder(order.id)
await refreshPendingSimOrder(order.id, order.simCardId)
await loadSim() await loadSim()
} catch (error) { } catch (error) {
const message = error.message || '充值下单失败' const message = error.message || '充值下单失败'
if (!orderCreated && /pending|未结|待支付|已有/.test(message) && pendingSimOrder.value?.simCardId === simRechargeCard.value?.id) {
const pendingForCard = findPendingSimOrderForCard(simRechargeCard.value?.id)
if (!orderCreated && /pending|未结|待支付|已有/.test(message) && pendingForCard) {
ui.toast(`${message};可先完成或取消上方待支付订单`) ui.toast(`${message};可先完成或取消上方待支付订单`)
} else { } else {
ui.toast(message) ui.toast(message)

Loading…
Cancel
Save