fix: KPI软删除+恢复入口+已归档筛选
This commit is contained in:
@@ -425,6 +425,15 @@ def delete_kpi(kpi_id: int, db: Session = Depends(get_db), user=WRITE_ROLES):
|
|||||||
return {"message": "已删除"}
|
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):
|
def kpi_to_dict(k):
|
||||||
d = {c.name: getattr(k, c.name) for c in k.__table__.columns}
|
d = {c.name: getattr(k, c.name) for c in k.__table__.columns}
|
||||||
# 附加战略地图信息
|
# 附加战略地图信息
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export const kpiApi = {
|
|||||||
create: (data: any) => api.post('/kpis', data),
|
create: (data: any) => api.post('/kpis', data),
|
||||||
update: (id: number, data: any) => api.put(`/kpis/${id}`, data),
|
update: (id: number, data: any) => api.put(`/kpis/${id}`, data),
|
||||||
delete: (id: number) => api.delete(`/kpis/${id}`),
|
delete: (id: number) => api.delete(`/kpis/${id}`),
|
||||||
|
restore: (id: number) => api.put(`/kpis/${id}/restore`),
|
||||||
listCategories: () => api.get('/kpis/categories'),
|
listCategories: () => api.get('/kpis/categories'),
|
||||||
associateMap: (id: number, data: any) => api.put(`/kpis/${id}/associate-map`, data),
|
associateMap: (id: number, data: any) => api.put(`/kpis/${id}/associate-map`, data),
|
||||||
// KPI-5: 五档评分
|
// KPI-5: 五档评分
|
||||||
|
|||||||
@@ -59,7 +59,11 @@
|
|||||||
<el-option label="学习成长" value="learning" />
|
<el-option label="学习成长" value="learning" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select v-model="searchCategory" placeholder="二级类别" clearable style="width:140px" @change="loadKpis">
|
<el-select v-model="searchCategory" placeholder="二级类别" clearable style="width:140px" @change="loadKpis">
|
||||||
<el-option v-for="c in allCategories" :key="c.value" :label="c.label" :value="c.value" />
|
<el-option v-for="c in categoryOptions" :key="c.value" :label="c.label" :value="c.value" />
|
||||||
|
</el-select>
|
||||||
|
<el-select v-model="searchStatus" placeholder="状态" clearable style="width:100px" @change="loadKpis">
|
||||||
|
<el-option label="活跃" value="active" />
|
||||||
|
<el-option label="已归档" value="disabled" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button type="primary" @click="loadKpis">查询</el-button>
|
<el-button type="primary" @click="loadKpis">查询</el-button>
|
||||||
<el-button @click="resetSearch">重置</el-button>
|
<el-button @click="resetSearch">重置</el-button>
|
||||||
@@ -139,7 +143,8 @@
|
|||||||
<el-table-column label="操作" width="100" fixed="right">
|
<el-table-column label="操作" width="100" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button size="small" text type="primary" @click.stop="$router.push('/kpis/' + row.id)">编辑</el-button>
|
<el-button size="small" text type="primary" @click.stop="$router.push('/kpis/' + row.id)">编辑</el-button>
|
||||||
<el-button size="small" text type="danger" @click.stop="doDelete(row.id)">删除</el-button>
|
<el-button v-if="row.status === 'active'" size="small" text type="danger" @click.stop="doDelete(row.id)">归档</el-button>
|
||||||
|
<el-button v-else size="small" text type="success" @click.stop="doRestore(row.id)">恢复</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -365,6 +370,7 @@ const pageSize = 20
|
|||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
const searchDimension = ref('')
|
const searchDimension = ref('')
|
||||||
const searchCategory = ref('')
|
const searchCategory = ref('')
|
||||||
|
const searchStatus = ref('active')
|
||||||
|
|
||||||
// ── 企业选择 ──
|
// ── 企业选择 ──
|
||||||
const entities = ref<any[]>([])
|
const entities = ref<any[]>([])
|
||||||
@@ -484,6 +490,7 @@ async function loadKpis() {
|
|||||||
if (searchKeyword.value) params.keyword = searchKeyword.value
|
if (searchKeyword.value) params.keyword = searchKeyword.value
|
||||||
if (searchDimension.value) params.dimension = searchDimension.value
|
if (searchDimension.value) params.dimension = searchDimension.value
|
||||||
if (searchCategory.value) params.category = searchCategory.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 (treeFilterDims.value.length > 0 && !params.dimension) params.dimension = treeFilterDims.value.join(',')
|
||||||
if (treeFilterCats.value.length > 0 && !params.category) params.category = treeFilterCats.value.join(',')
|
if (treeFilterCats.value.length > 0 && !params.category) params.category = treeFilterCats.value.join(',')
|
||||||
|
|
||||||
@@ -533,7 +540,7 @@ function onSelectionChange(rows: any[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function batchDelete() {
|
function batchDelete() {
|
||||||
ElMessageBox.confirm(`确定删除选中的 ${selectedIds.value.length} 条KPI?`, '提示').then(async () => {
|
ElMessageBox.confirm(`确定归档选中的 ${selectedIds.value.length} 条KPI?`, '提示').then(async () => {
|
||||||
for (const id of selectedIds.value) {
|
for (const id of selectedIds.value) {
|
||||||
try { await kpiApi.delete(id) } catch (e) {}
|
try { await kpiApi.delete(id) } catch (e) {}
|
||||||
}
|
}
|
||||||
@@ -544,6 +551,14 @@ function batchDelete() {
|
|||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doRestore(id: number) {
|
||||||
|
ElMessageBox.confirm('确定恢复此KPI?', '提示').then(async () => {
|
||||||
|
await kpiApi.restore(id)
|
||||||
|
ElMessage.success('已恢复')
|
||||||
|
loadKpis()
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
function batchExport() {
|
function batchExport() {
|
||||||
const header = '编码,名称,维度,二级类别,目标值,频率,数据源,负责人,计算公式'
|
const header = '编码,名称,维度,二级类别,目标值,频率,数据源,负责人,计算公式'
|
||||||
const rows = kpis.value.map((k: any) =>
|
const rows = kpis.value.map((k: any) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user