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) =>