|
|
|
@ -136,7 +136,9 @@ |
|
|
|
<template #usage="{ row }">{{ row.lastSyncAt ? `${Number(row.usedGb || 0).toFixed(1)} / ${row.planGb || 0} GB` : '暂无运营商同步数据' }}</template> |
|
|
|
<template #status="{ row }"><span class="carrier-status" :class="simStatus(row).cls"><i></i>{{ simStatus(row).name }}</span></template> |
|
|
|
<template #lastSyncAt="{ row }">{{ fmtTime(row.lastSyncAt) }}</template> |
|
|
|
<template #actions><span>运营商通道未接入</span></template> |
|
|
|
<template #actions="{ row }"> |
|
|
|
<t-button variant="text" theme="primary" @click="openSimRecharge(row)">充值</t-button> |
|
|
|
</template> |
|
|
|
</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="account-subsection-title"><h3>通信卡充值记录</h3><span>共 {{ simRechargeTotal }} 条</span></div> |
|
|
|
@ -144,7 +146,7 @@ |
|
|
|
<template #simCardId="{ row }">{{ cardLabel(row.simCardId) }}</template> |
|
|
|
<template #amountGb="{ row }"><strong>{{ row.amountGb }} GB</strong></template> |
|
|
|
<template #totalPrice="{ row }"><strong>{{ money(row.totalPrice) }}</strong></template> |
|
|
|
<template #payStatus="{ row }"><em>{{ payStatusName(row.payStatus) }}</em></template> |
|
|
|
<template #payStatus="{ row }"><em>{{ payStatusName(row.payStatus || row.paymentStatus) }}</em></template> |
|
|
|
<template #rechargeStatus="{ row }"><em :class="{ processing: row.rechargeStatus === 'pending' }">{{ rechargeStatusName(row.rechargeStatus) }}</em></template> |
|
|
|
<template #createdAt="{ row }">{{ fmtTime(row.createdAt) }}</template> |
|
|
|
</t-table> |
|
|
|
@ -227,6 +229,35 @@ |
|
|
|
<t-button theme="primary" @click="changePassword">确认修改</t-button> |
|
|
|
</template> |
|
|
|
</t-dialog> |
|
|
|
<t-dialog |
|
|
|
v-model:visible="simRechargeOpen" |
|
|
|
header="通信卡充值" |
|
|
|
width="480px" |
|
|
|
destroy-on-close |
|
|
|
dialog-class-name="recharge-modal" |
|
|
|
placement="center" |
|
|
|
> |
|
|
|
<p>ICCID:{{ simRechargeCard?.iccid || '--' }}</p> |
|
|
|
<label> |
|
|
|
<span>选择套餐</span> |
|
|
|
<t-radio-group v-model="selectedSimPackageId" :disabled="!simPackages.length || simRecharging"> |
|
|
|
<t-radio v-for="pkg in simPackages" :key="pkg.id" :value="pkg.id"> |
|
|
|
{{ pkg.name }} · {{ pkg.amountGb }}GB · {{ moneyFromFen(pkg.saleFeeFen) }} |
|
|
|
<small v-if="pkg.validityMonths"> / {{ pkg.validityMonths }}个月</small> |
|
|
|
</t-radio> |
|
|
|
</t-radio-group> |
|
|
|
<small v-if="!simPackages.length">暂无可用通信卡套餐</small> |
|
|
|
</label> |
|
|
|
<template #footer> |
|
|
|
<t-button variant="outline" @click="simRechargeOpen = false">取消</t-button> |
|
|
|
<t-button |
|
|
|
theme="primary" |
|
|
|
:loading="simRecharging" |
|
|
|
:disabled="!selectedSimPackageId || !simPackages.length" |
|
|
|
@click="submitSimRecharge" |
|
|
|
>创建并支付</t-button> |
|
|
|
</template> |
|
|
|
</t-dialog> |
|
|
|
</section> |
|
|
|
</template> |
|
|
|
|
|
|
|
@ -262,6 +293,11 @@ const orders = ref([]); const orderTotal = ref(0); const orderPages = ref(1); co |
|
|
|
const usage = ref([]); const usageTotal = ref(0); const usagePages = ref(1); const usagePageNum = ref(1) |
|
|
|
const simCards = ref([]); const simTotal = ref(0); const simPages = ref(1); const simPageNum = ref(1) |
|
|
|
const simRechargeLogs = ref([]); const simRechargeTotal = ref(0); const simRechargePages = ref(1); const simRechargePageNum = ref(1) |
|
|
|
const simPackages = ref([]) |
|
|
|
const simRechargeOpen = ref(false) |
|
|
|
const simRechargeCard = ref(null) |
|
|
|
const selectedSimPackageId = ref(0) |
|
|
|
const simRecharging = ref(false) |
|
|
|
const editOpen = ref(false); const saving = ref(false); const editForm = ref({ name: '', email: '' }) |
|
|
|
|
|
|
|
const orderColumns = [ |
|
|
|
@ -397,6 +433,14 @@ async function loadTrafficPackages() { |
|
|
|
trafficPackages.value = [] |
|
|
|
} |
|
|
|
} |
|
|
|
async function loadSimPackages() { |
|
|
|
try { |
|
|
|
const list = await request.get(urls.SIM_PACKAGES) |
|
|
|
simPackages.value = Array.isArray(list) ? list : [] |
|
|
|
} catch { |
|
|
|
simPackages.value = [] |
|
|
|
} |
|
|
|
} |
|
|
|
async function load() { |
|
|
|
const results = await Promise.allSettled([ |
|
|
|
loadProfile(), |
|
|
|
@ -406,7 +450,8 @@ async function load() { |
|
|
|
loadSim(), |
|
|
|
loadDeviceCount(), |
|
|
|
loadAccountExtensions(), |
|
|
|
loadTrafficPackages() |
|
|
|
loadTrafficPackages(), |
|
|
|
loadSimPackages() |
|
|
|
]) |
|
|
|
if (results.some((result) => result.status === 'rejected')) ui.toast('部分账户数据加载失败') |
|
|
|
} |
|
|
|
@ -461,6 +506,39 @@ async function cancelTrafficOrder(id) { |
|
|
|
ui.toast(error.message || '取消失败') |
|
|
|
} |
|
|
|
} |
|
|
|
function openSimRecharge(card) { |
|
|
|
simRechargeCard.value = card |
|
|
|
selectedSimPackageId.value = simPackages.value[0]?.id || 0 |
|
|
|
simRechargeOpen.value = true |
|
|
|
} |
|
|
|
async function submitSimRecharge() { |
|
|
|
if (!simRechargeCard.value?.id) return |
|
|
|
if (!selectedSimPackageId.value) { |
|
|
|
ui.toast('请选择套餐') |
|
|
|
return |
|
|
|
} |
|
|
|
simRecharging.value = true |
|
|
|
let orderCreated = false |
|
|
|
try { |
|
|
|
const order = await request.post( |
|
|
|
urls.SIM_CARD_RECHARGE_ORDERS(simRechargeCard.value.id), |
|
|
|
{ packageId: Number(selectedSimPackageId.value) } |
|
|
|
) |
|
|
|
orderCreated = true |
|
|
|
const payment = await createPayment('sim_recharge_order', order.id) |
|
|
|
ui.toast(describePayment(payment)) |
|
|
|
simRechargeOpen.value = false |
|
|
|
await loadSim() |
|
|
|
} catch (error) { |
|
|
|
ui.toast(error.message || '充值下单失败') |
|
|
|
if (orderCreated) { |
|
|
|
simRechargeOpen.value = false |
|
|
|
await loadSim() |
|
|
|
} |
|
|
|
} finally { |
|
|
|
simRecharging.value = false |
|
|
|
} |
|
|
|
} |
|
|
|
async function saveProfile() { saving.value = true; try { const updated = await request.put(urls.ACCOUNT_PROFILE, editForm.value); profile.value = updated; userStore.user = { ...(userStore.user || {}), ...updated }; localStorage.setItem('user', JSON.stringify(userStore.user)); editOpen.value = false; ui.toast('账户资料已保存') } catch (error) { ui.toast(error.message || '保存账户资料失败') } finally { saving.value = false } } |
|
|
|
onMounted(load) |
|
|
|
</script> |
|
|
|
|