From 5d7873e05e5ab0c3068fee0c11e55ef18a53727e Mon Sep 17 00:00:00 2001 From: Hermes CI Fix Date: Mon, 20 Jul 2026 10:21:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20KPI=E8=BD=AF=E5=88=A0=E9=99=A4+=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E5=85=A5=E5=8F=A3+=E5=B7=B2=E5=BD=92=E6=A1=A3?= =?UTF-8?q?=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/kpis.py | 9 +++++++++ frontend/src/api/index.ts | 1 + frontend/src/views/KPIList.vue | 21 ++++++++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/backend/app/api/kpis.py b/backend/app/api/kpis.py index 58303c18..0c21d3f8 100644 --- a/backend/app/api/kpis.py +++ b/backend/app/api/kpis.py @@ -425,6 +425,15 @@ def delete_kpi(kpi_id: int, db: Session = Depends(get_db), user=WRITE_ROLES): return {"message": "已删除"} +@router.put("/{kpi_id}/restore") +def restore_kpi(kpi_id: int, db: Session = Depends(get_db), user=WRITE_ROLES): + kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first() + if kpi: + kpi.status = "active" + db.commit() + return {"message": "已恢复"} + + def kpi_to_dict(k): d = {c.name: getattr(k, c.name) for c in k.__table__.columns} # 附加战略地图信息 diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 0dafd47b..3efe72ce 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -34,6 +34,7 @@ export const kpiApi = { create: (data: any) => api.post('/kpis', data), update: (id: number, data: any) => api.put(`/kpis/${id}`, data), delete: (id: number) => api.delete(`/kpis/${id}`), + restore: (id: number) => api.put(`/kpis/${id}/restore`), listCategories: () => api.get('/kpis/categories'), associateMap: (id: number, data: any) => api.put(`/kpis/${id}/associate-map`, data), // KPI-5: 五档评分 diff --git a/frontend/src/views/KPIList.vue b/frontend/src/views/KPIList.vue index dbd90bd3..2c60f536 100644 --- a/frontend/src/views/KPIList.vue +++ b/frontend/src/views/KPIList.vue @@ -59,7 +59,11 @@ - + + + + + 查询 重置 @@ -139,7 +143,8 @@ @@ -365,6 +370,7 @@ const pageSize = 20 const searchKeyword = ref('') const searchDimension = ref('') const searchCategory = ref('') +const searchStatus = ref('active') // ── 企业选择 ── const entities = ref([]) @@ -484,6 +490,7 @@ async function loadKpis() { if (searchKeyword.value) params.keyword = searchKeyword.value if (searchDimension.value) params.dimension = searchDimension.value if (searchCategory.value) params.category = searchCategory.value + if (searchStatus.value) params.status = searchStatus.value if (treeFilterDims.value.length > 0 && !params.dimension) params.dimension = treeFilterDims.value.join(',') if (treeFilterCats.value.length > 0 && !params.category) params.category = treeFilterCats.value.join(',') @@ -533,7 +540,7 @@ function onSelectionChange(rows: any[]) { } function batchDelete() { - ElMessageBox.confirm(`确定删除选中的 ${selectedIds.value.length} 条KPI?`, '提示').then(async () => { + ElMessageBox.confirm(`确定归档选中的 ${selectedIds.value.length} 条KPI?`, '提示').then(async () => { for (const id of selectedIds.value) { try { await kpiApi.delete(id) } catch (e) {} } @@ -544,6 +551,14 @@ function batchDelete() { }).catch(() => {}) } +function doRestore(id: number) { + ElMessageBox.confirm('确定恢复此KPI?', '提示').then(async () => { + await kpiApi.restore(id) + ElMessage.success('已恢复') + loadKpis() + }).catch(() => {}) +} + function batchExport() { const header = '编码,名称,维度,二级类别,目标值,频率,数据源,负责人,计算公式' const rows = kpis.value.map((k: any) =>