diff --git a/src/views/TrafficOpsView/TrafficOpsView.vue b/src/views/TrafficOpsView/TrafficOpsView.vue
index c05503f..609cd87 100644
--- a/src/views/TrafficOpsView/TrafficOpsView.vue
+++ b/src/views/TrafficOpsView/TrafficOpsView.vue
@@ -5,6 +5,11 @@
流量运营
管理云媒体流量套餐、平台采购入池与账务流水
+
+
+ 测试发放
+
+
@@ -339,6 +344,67 @@
确认录入
+
+
+
+
+ 取消
+ 确认发放
+
+
@@ -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;
+}