- 后端新增 POST /api/cma/action-plans/coso-generate-actions:未通过条目→action_plans, 账套取 token 绑定(忽略 body entity_id)、幂等键 (entity_id,title)、不写 auto_verify_rule - 前端 ActionPlanLibrary.vue 按钮接 @click(含未通过条数提示 + 二次确认 + 生成后刷新并跳列表) - api 客户端补 cosoGenerateActions - 新增 tests/test_coso_generate_actions_20260921.py(生成/幂等/隔离/未认证/归属校验/空集)
This commit is contained in:
@@ -202,6 +202,7 @@ export const actionPlanApi = {
|
||||
update: (id: number, data: any) => api.put(`/action-plans/${id}`, data),
|
||||
delete: (id: number) => api.delete(`/action-plans/${id}`),
|
||||
cosoChecklist: (params?: any) => api.get('/action-plans/coso-checklist', { params }),
|
||||
cosoGenerateActions: (data?: any) => api.post('/action-plans/coso-generate-actions', data || {}),
|
||||
stats: () => api.get('/action-plans/stats'),
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,8 @@
|
||||
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||
<el-button size="small" @click="loadCosoChecklist" :loading="cosoLoading">刷新</el-button>
|
||||
<el-button v-if="cosoData" type="primary" size="small" style="margin-left:12px;">生成改善行动</el-button>
|
||||
<el-button v-if="cosoData" type="primary" size="small" style="margin-left:12px;"
|
||||
:loading="cosoGenerating" @click="generateCosoActions">生成改善行动<span v-if="cosoFailedCount">({{ cosoFailedCount }})</span></el-button>
|
||||
</div>
|
||||
|
||||
<div v-if="cosoData">
|
||||
@@ -667,6 +668,38 @@ async function loadCosoChecklist() {
|
||||
cosoLoading.value = false
|
||||
}
|
||||
|
||||
const cosoGenerating = ref(false)
|
||||
// 自检未通过(passed=false)条目数——即「生成改善行动」将覆盖的范围
|
||||
const cosoFailedCount = computed(() => {
|
||||
const els = cosoData.value?.elements || []
|
||||
return els.reduce((n: number, el: any) => n + (el.items || []).filter((it: any) => !it.passed).length, 0)
|
||||
})
|
||||
|
||||
async function generateCosoActions() {
|
||||
if (!cosoData.value) return
|
||||
const n = cosoFailedCount.value
|
||||
if (n === 0) {
|
||||
ElMessage.info('当前自检没有未通过条目,无需生成改善行动')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`将把自检中 ${n} 条未通过条目生成改善行动(已存在的不会重复生成),是否继续?`,
|
||||
'生成改善行动'
|
||||
)
|
||||
} catch { return }
|
||||
cosoGenerating.value = true
|
||||
try {
|
||||
const r: any = await actionPlanApi.cosoGenerateActions({})
|
||||
const created = r?.created ?? 0
|
||||
const skipped = r?.skipped ?? 0
|
||||
ElMessage.success(`已生成 ${created} 条改善行动${skipped ? `,跳过 ${skipped} 条已存在` : ''}`)
|
||||
await Promise.all([loadData(), loadStats()])
|
||||
if (created > 0) activeTab.value = 'plans' // 切到行动方案列表即可确认
|
||||
} catch { ElMessage.error('生成改善行动失败') }
|
||||
cosoGenerating.value = false
|
||||
}
|
||||
|
||||
// ── 初始化 ──
|
||||
onMounted(async () => {
|
||||
loadStats()
|
||||
|
||||
Reference in New Issue
Block a user