Browse Source

feat: add traffic test-grant dialog shell

main
xiaosi 3 weeks ago
parent
commit
69448ae193
  1. 133
      src/views/TrafficOpsView/TrafficOpsView.vue

133
src/views/TrafficOpsView/TrafficOpsView.vue

@ -5,6 +5,11 @@
<h1>流量运营</h1>
<span>管理云媒体流量套餐平台采购入池与账务流水</span>
</div>
<div class="page-actions">
<t-button theme="primary" @click="openGrant">
<svg><use href="#i-plus" /></svg>测试发放
</t-button>
</div>
</header>
<div class="business-workspace">
@ -339,6 +344,67 @@
<t-button theme="primary" @click="submitPurchase">确认录入</t-button>
</template>
</t-dialog>
<t-dialog
v-model:visible="grantModalVisible"
header="测试发放流量"
width="520px"
destroy-on-close
dialog-class-name="add-dock-dialog"
:close-on-overlay-click="false"
placement="center"
@closed="resetGrantForm"
>
<form novalidate @submit.prevent="submitGrant">
<label>
<span>搜索用户</span>
<t-select
v-model="grantSelectedUserId"
filterable
clearable
placeholder="输入姓名 / 手机号 / 邮箱搜索"
:options="grantUserOptions"
:loading="grantUserSearching"
style="width: 100%"
@search="searchGrantUsers"
@change="onGrantUserPicked"
@clear="onGrantUserCleared"
/>
</label>
<label>
<span>用户 ID<b>*</b></span>
<t-input
v-model="grantForm.userId"
clearable
placeholder="可手填,或从上方搜索选中"
/>
</label>
<label>
<span>额度(GB)<b>*</b></span>
<t-input-number
v-model="grantForm.amountGb"
theme="normal"
:min="1"
:step="1"
:decimal-places="0"
style="width: 100%"
/>
</label>
<label>
<span>原因<b>*</b></span>
<t-input v-model="grantForm.reason" clearable placeholder="如 live test" />
</label>
<p v-if="grantFormError" class="form-error">{{ grantFormError }}</p>
<div v-if="grantResultBalanceText" class="grant-result">
<span>最新余额</span>
<strong>{{ grantResultBalanceText }}</strong>
</div>
</form>
<template #footer>
<t-button variant="outline" @click="grantModalVisible = false">取消</t-button>
<t-button theme="primary" :loading="grantSubmitting" @click="submitGrant">确认发放</t-button>
</template>
</t-dialog>
</section>
</template>
@ -665,6 +731,54 @@ async function submitPurchase() {
}
}
const grantModalVisible = ref(false)
const grantSubmitting = ref(false)
const grantUserSearching = ref(false)
const grantFormError = ref('')
const grantResultBalanceText = ref('')
const grantSelectedUserId = ref('')
const grantUserOptions = ref([])
const grantForm = reactive({
userId: '',
amountGb: 10,
reason: 'live test'
})
function resetGrantForm() {
grantForm.userId = ''
grantForm.amountGb = 10
grantForm.reason = 'live test'
grantSelectedUserId.value = ''
grantUserOptions.value = []
grantFormError.value = ''
grantResultBalanceText.value = ''
grantSubmitting.value = false
grantUserSearching.value = false
}
function openGrant() {
resetGrantForm()
grantModalVisible.value = true
}
function onGrantUserPicked(val) {
if (val == null || val === '') return
grantForm.userId = String(val)
}
function onGrantUserCleared() {
grantSelectedUserId.value = ''
}
async function searchGrantUsers(_keyword) {
// Task 3: remote user search
}
async function submitGrant() {
// Task 3: validate + POST test-grants
}
const ledgerList = ref([])
const ledgerTotal = ref(0)
const ledgerPageNum = ref(1)
@ -777,6 +891,25 @@ onMounted(() => {
color: var(--muted);
font-size: 11px;
}
.grant-result {
margin-top: 12px;
padding: 10px 12px;
border: 1px solid #d7e4ee;
border-radius: 4px;
background: #f5f9fc;
}
.grant-result span {
display: block;
color: #6c7d88;
font-size: 11px;
}
.grant-result strong {
display: block;
margin-top: 4px;
color: #246fae;
font-size: 18px;
}
</style>
<style>

Loading…
Cancel
Save