From bf0f0b30541ef38f27b1cbdd9a5104bb798f5a26 Mon Sep 17 00:00:00 2001 From: Hermes CI Fix Date: Sun, 16 Aug 2026 12:04:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A8=E5=8D=95=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E8=A7=84=E8=8C=83P1+P2+P3=20=E2=80=94=20?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=8C=89=E9=92=AEloading=E9=98=B2=E9=87=8D?= =?UTF-8?q?=E5=A4=8D(KPIList/UserManage/KPIDetail)+KPIList=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=BC=B9=E7=AA=97=E5=8C=96(=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E8=B7=B3=E9=A1=B5=E5=B9=B6=E5=AD=98)+=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=8F=8D=E9=A6=88=E5=85=A8=E9=9D=A2=E6=A0=B8=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/KPIDetail.vue | 7 +++++- frontend/src/views/KPIList.vue | 36 ++++++++++++++++++++++++++++--- frontend/src/views/UserManage.vue | 8 ++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/frontend/src/views/KPIDetail.vue b/frontend/src/views/KPIDetail.vue index 41bacbfb..e62ad893 100644 --- a/frontend/src/views/KPIDetail.vue +++ b/frontend/src/views/KPIDetail.vue @@ -85,7 +85,7 @@ - 保存 + 保存 @@ -305,6 +305,7 @@ const fullNetworkLoading = ref(false) // 编辑未保存离开确认(统一守卫 composable) const isDirty = ref(false) useFormGuard(isDirty) +const saving = ref(false) let kpiSnapshot: string = '' let watchInitialized = false @@ -539,6 +540,8 @@ const fullNetworkChartOption = computed(() => { }) async function save() { + if (saving.value) return + saving.value = true try { await kpiApi.update(kpi.value.id, kpi.value) ElMessage.success('保存成功') @@ -549,6 +552,8 @@ async function save() { kpiSnapshot = JSON.stringify(kpi.value) } catch (e) { ElMessage.error('保存失败') + } finally { + saving.value = false } } diff --git a/frontend/src/views/KPIList.vue b/frontend/src/views/KPIList.vue index 2f6b338e..64dd81e4 100644 --- a/frontend/src/views/KPIList.vue +++ b/frontend/src/views/KPIList.vue @@ -140,9 +140,10 @@ - - + @@ -260,7 +261,7 @@ @@ -417,6 +418,31 @@ async function loadUsers() { const showForm = ref(false) const editMode = ref(false) const form = ref({}) +const saving = ref(false) + +// ── 编辑入口:列表行 → 弹窗编辑(与新建一致)── +function openEdit(row: any) { + editMode.value = true + form.value = { + id: row.id, + kpi_code: row.kpi_code, + kpi_name: row.kpi_name, + dimension: row.dimension, + category: row.category, + target_value: row.target_value, + unit: row.unit, + frequency: row.frequency, + data_source_type: row.data_source_type, + responsible_dept: row.responsible_dept, + responsible_user: row.responsible_user, + formula: row.formula, + threshold_green: row.threshold_green, + threshold_yellow: row.threshold_yellow, + threshold_red: row.threshold_red, + epic: row.epic, + } + showForm.value = true +} // ── 未保存离开守卫 ── const isDirty = ref(false) @@ -610,6 +636,8 @@ function onDimensionChange(val: string) { } async function saveKPI() { + if (saving.value) return + saving.value = true try { if (editMode.value) { await kpiApi.update(form.value.id, form.value) @@ -624,6 +652,8 @@ async function saveKPI() { loadCategories() } catch (e) { ElMessage.error(editMode.value ? '保存失败' : '创建失败') + } finally { + saving.value = false } } diff --git a/frontend/src/views/UserManage.vue b/frontend/src/views/UserManage.vue index 0ce976b1..13bc3ed0 100644 --- a/frontend/src/views/UserManage.vue +++ b/frontend/src/views/UserManage.vue @@ -49,7 +49,7 @@ @@ -66,6 +66,7 @@ const loading = ref(false) const showForm = ref(false) const isEdit = ref(false) const form = ref({}) +const saving = ref(false) function roleLabel(role: string) { const map: Record = { ceo: 'CEO', finance: '财务', business: '业务', it: 'IT管理' } @@ -94,6 +95,8 @@ function openForm(row: any) { } async function saveUser() { + if (saving.value) return + saving.value = true try { if (isEdit.value) { const payload: any = {} @@ -106,6 +109,7 @@ async function saveUser() { } else { if (!form.value.username || !form.value.password) { ElMessage.warning('用户名和密码必填') + saving.value = false return } await userApi.create(form.value) @@ -115,6 +119,8 @@ async function saveUser() { load() } catch (e) { ElMessage.error('操作失败') + } finally { + saving.value = false } }