From 2609ea3f79cc2dcf470ce666b3f5b219aa659186 Mon Sep 17 00:00:00 2001 From: huangping Date: Wed, 27 May 2026 08:37:16 +0800 Subject: [PATCH] fix: update stale labels and add callback backlog stats card Fixed login page (removed I1 tag, updated demo accounts). Added backlog stats bar to CallbackInboxView. Fixed size:500 to size:200 across all list views to match backend @Max(200) validation. Co-authored-by: Sisyphus --- .../src/views/CallbackInboxView.vue | 29 ++++++++++++++++++- .../src/views/ContractWizardView.vue | 4 +-- .../src/views/ContractsView.vue | 4 +-- .../src/views/DeliveriesView.vue | 2 +- .../src/views/DeliveryBatchDetailView.vue | 2 +- .../src/views/DeliveryBatchWizardView.vue | 4 +-- .../src/views/LicenseSnDetailView.vue | 2 +- .../src/views/LicenseSnListView.vue | 2 +- .../src/views/LicenseSnWizardView.vue | 2 +- .../src/views/LoginView.vue | 11 +++++-- .../src/views/ProjectsView.vue | 2 +- 11 files changed, 48 insertions(+), 16 deletions(-) diff --git a/web/delivery-platform-ui/src/views/CallbackInboxView.vue b/web/delivery-platform-ui/src/views/CallbackInboxView.vue index f247501..114cf3f 100644 --- a/web/delivery-platform-ui/src/views/CallbackInboxView.vue +++ b/web/delivery-platform-ui/src/views/CallbackInboxView.vue @@ -20,6 +20,18 @@ +
+ + ⏳ 待处理 {{ backlog.totalPending }} + + + ❌ 失败 {{ backlog.totalFailed }} + + + ⏰ 最久未处理 {{ backlog.oldestPendingHours }}h + +
+ @@ -84,6 +96,7 @@ import { ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { ElMessage } from "element-plus"; import { useAuthStore } from "../stores/auth"; +import axios from "axios"; import { listCallbackInbox, replayCallbackWebhookDelivery, simulateCallback } from "../api/platform"; import { apiErrorMessage } from "../utils/apiErrorMessage"; @@ -103,6 +116,7 @@ const selectedCallbacks = ref([]); const simDialogVisible = ref(false); const simulating = ref(false); const simForm = ref({ eventType: 'sn:post_activate', snCode: '', rawPayload: '{}' }); +const backlog = ref(null); function handleSelectionChange(val) { selectedCallbacks.value = val; @@ -123,9 +137,16 @@ async function handleBatchRetry() { load(); } +async function loadBacklog() { + try { + const { data } = await axios.get('/api/v1/callback-inbox/stats/backlog'); + backlog.value = data; + } catch { /* non-critical */ } +} + onMounted(async () => { auth.restoreAxiosAuth(); - await load(); + await Promise.all([load(), loadBacklog()]); }); function onSizeChange() { @@ -226,4 +247,10 @@ function goDetail(id) { display: flex; justify-content: flex-end; } +.backlog-bar { + display: flex; gap: 24px; padding: 8px 0 12px; font-size: 13px; color: #606266; +} +.bl-item strong { font-size: 18px; margin: 0 2px; } +.bl-warn { color: #E6A23C; } +.bl-danger { color: #D54941; } diff --git a/web/delivery-platform-ui/src/views/ContractWizardView.vue b/web/delivery-platform-ui/src/views/ContractWizardView.vue index 9efc519..5746768 100644 --- a/web/delivery-platform-ui/src/views/ContractWizardView.vue +++ b/web/delivery-platform-ui/src/views/ContractWizardView.vue @@ -185,7 +185,7 @@ function onCustomerChange() { async function loadCustomers() { customersLoading.value = true; try { - const { data } = await listCustomers({ page: 0, size: 500 }); + const { data } = await listCustomers({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; customerOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { @@ -199,7 +199,7 @@ async function loadCustomers() { async function loadAllProjects() { projectsLoading.value = true; try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; projectOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { diff --git a/web/delivery-platform-ui/src/views/ContractsView.vue b/web/delivery-platform-ui/src/views/ContractsView.vue index 89a2b71..9263f15 100644 --- a/web/delivery-platform-ui/src/views/ContractsView.vue +++ b/web/delivery-platform-ui/src/views/ContractsView.vue @@ -147,8 +147,8 @@ function formatDateTime(v) { async function loadCustomerProjectMaps() { try { const [cRes, pRes] = await Promise.all([ - listCustomers({ page: 0, size: 500 }), - listProjects({ page: 0, size: 500 }), + listCustomers({ page: 0, size: 200 }), + listProjects({ page: 0, size: 200 }), ]); const cBody = cRes.data && typeof cRes.data === "object" ? cRes.data : {}; const pBody = pRes.data && typeof pRes.data === "object" ? pRes.data : {}; diff --git a/web/delivery-platform-ui/src/views/DeliveriesView.vue b/web/delivery-platform-ui/src/views/DeliveriesView.vue index 90f5027..2be1547 100644 --- a/web/delivery-platform-ui/src/views/DeliveriesView.vue +++ b/web/delivery-platform-ui/src/views/DeliveriesView.vue @@ -136,7 +136,7 @@ function formatDateTime(v) { async function loadProjects() { try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; const list = Array.isArray(body.content) ? body.content : []; projectOptions.value = list; diff --git a/web/delivery-platform-ui/src/views/DeliveryBatchDetailView.vue b/web/delivery-platform-ui/src/views/DeliveryBatchDetailView.vue index 8cd3a70..597a521 100644 --- a/web/delivery-platform-ui/src/views/DeliveryBatchDetailView.vue +++ b/web/delivery-platform-ui/src/views/DeliveryBatchDetailView.vue @@ -246,7 +246,7 @@ function formatDateTime(v) { async function loadProjectMap() { try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; const list = Array.isArray(body.content) ? body.content : []; const m = new Map(); diff --git a/web/delivery-platform-ui/src/views/DeliveryBatchWizardView.vue b/web/delivery-platform-ui/src/views/DeliveryBatchWizardView.vue index ebbdb3e..5307b1a 100644 --- a/web/delivery-platform-ui/src/views/DeliveryBatchWizardView.vue +++ b/web/delivery-platform-ui/src/views/DeliveryBatchWizardView.vue @@ -127,7 +127,7 @@ function contractOptionLabel(c) { async function loadProjects() { projectsLoading.value = true; try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; projectOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { @@ -141,7 +141,7 @@ async function loadProjects() { async function loadContracts() { contractsLoading.value = true; try { - const { data } = await listContracts({ page: 0, size: 500 }); + const { data } = await listContracts({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; contractOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { diff --git a/web/delivery-platform-ui/src/views/LicenseSnDetailView.vue b/web/delivery-platform-ui/src/views/LicenseSnDetailView.vue index 2d90da6..7fb087e 100644 --- a/web/delivery-platform-ui/src/views/LicenseSnDetailView.vue +++ b/web/delivery-platform-ui/src/views/LicenseSnDetailView.vue @@ -204,7 +204,7 @@ function goList() { async function loadProjects() { projectsLoading.value = true; try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; projectOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { diff --git a/web/delivery-platform-ui/src/views/LicenseSnListView.vue b/web/delivery-platform-ui/src/views/LicenseSnListView.vue index 9b01eea..2806cf9 100644 --- a/web/delivery-platform-ui/src/views/LicenseSnListView.vue +++ b/web/delivery-platform-ui/src/views/LicenseSnListView.vue @@ -185,7 +185,7 @@ function formatDateTime(v) { async function loadProjects() { try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; const list = Array.isArray(body.content) ? body.content : []; projectOptions.value = list; diff --git a/web/delivery-platform-ui/src/views/LicenseSnWizardView.vue b/web/delivery-platform-ui/src/views/LicenseSnWizardView.vue index 0da49ce..027f113 100644 --- a/web/delivery-platform-ui/src/views/LicenseSnWizardView.vue +++ b/web/delivery-platform-ui/src/views/LicenseSnWizardView.vue @@ -90,7 +90,7 @@ function goBack() { async function loadProjects() { projectsLoading.value = true; try { - const { data } = await listProjects({ page: 0, size: 500 }); + const { data } = await listProjects({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; projectOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) { diff --git a/web/delivery-platform-ui/src/views/LoginView.vue b/web/delivery-platform-ui/src/views/LoginView.vue index 7c6dc6c..c1be4cc 100644 --- a/web/delivery-platform-ui/src/views/LoginView.vue +++ b/web/delivery-platform-ui/src/views/LoginView.vue @@ -1,7 +1,7 @@ @@ -30,7 +30,12 @@ const router = useRouter(); const route = useRoute(); const auth = useAuthStore(); -onMounted(() => auth.restoreAxiosAuth()); +onMounted(() => { + auth.restoreAxiosAuth() + if (route.query.timeout === '1') { + ElMessage.warning('会话已超时,请重新登录') + } +}); async function onSubmit() { loading.value = true; diff --git a/web/delivery-platform-ui/src/views/ProjectsView.vue b/web/delivery-platform-ui/src/views/ProjectsView.vue index edb4658..7ac049e 100644 --- a/web/delivery-platform-ui/src/views/ProjectsView.vue +++ b/web/delivery-platform-ui/src/views/ProjectsView.vue @@ -391,7 +391,7 @@ async function loadPhaseDictionary() { async function loadCustomersForSelect() { customersLoading.value = true; try { - const { data } = await listCustomers({ page: 0, size: 500 }); + const { data } = await listCustomers({ page: 0, size: 200 }); const body = data && typeof data === "object" ? data : {}; customerOptions.value = Array.isArray(body.content) ? body.content : []; } catch (e) {