feat(P1-1): KPI单值人工录入 — 新增POST /kpis/{id}/values + 前端录入弹窗

M02绩效管理闭环工具:客户/流程/学习层台账数据可直接在KPI详情录入
- 后端: 单值录入(期间+实际值), 同期间重复自动更新, 来源=manual/verified
- 前端: 历史数据Tab新增'录入数据'按钮+弹窗(期间选择+数值输入)
- 验证: C_SATISFACTION 2026-08录入85→更新88, 历史数据联动显示
This commit is contained in:
Hermes CI Fix
2026-08-26 22:34:23 +08:00
parent ba8e2f112b
commit 35974514da
2 changed files with 106 additions and 1 deletions
+55
View File
@@ -145,6 +145,9 @@
</el-tab-pane>
<el-tab-pane label="历史数据" name="history">
<div style="display:flex;justify-content:flex-end;margin-bottom:8px;">
<el-button size="small" type="primary" plain @click="openAddValueDialog"> 录入数据</el-button>
</div>
<v-chart :option="chartOption" autoresize class="full-width-chart" />
<el-table :data="values" size="small" class="data-table">
<el-table-column prop="period" label="期间" width="100" />
@@ -311,6 +314,26 @@
<el-button @click="showFullNetwork = false">关闭</el-button>
</template>
</MyDialog>
<!-- 录入数据对话框 -->
<MyDialog v-model="showAddValue" title="录入KPI数据" :width="420">
<el-form label-width="80px">
<el-form-item label="KPI">
<span>{{ kpi?.kpi_code }} {{ kpi?.kpi_name }}</span>
</el-form-item>
<el-form-item label="期间">
<el-date-picker v-model="addValueForm.period" type="month" value-format="YYYY-MM" placeholder="选择月份" style="width:200px;" />
</el-form-item>
<el-form-item label="实际值">
<el-input-number v-model="addValueForm.actual_value" :precision="2" :step="1" style="width:200px;" />
<span style="margin-left:6px;color:#999;font-size:12px;">{{ kpi?.unit || '' }}</span>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showAddValue = false">取消</el-button>
<el-button type="primary" :loading="addValueSaving" @click="submitAddValue">保存</el-button>
</template>
</MyDialog>
</div>
</template>
@@ -328,6 +351,38 @@ const route = useRoute()
const kpi = ref<any>(null)
const values = ref<any[]>([])
//
const showAddValue = ref(false)
const addValueSaving = ref(false)
const addValueForm = ref({ period: '', actual_value: 0 })
function openAddValueDialog() {
const now = new Date()
addValueForm.value = {
period: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`,
actual_value: 0,
}
showAddValue.value = true
}
async function submitAddValue() {
if (!addValueForm.value.period) { ElMessage.warning('请选择期间'); return }
addValueSaving.value = true
try {
const r: any = await api.post(`/kpis/${kpi.value.id}/values`, {
period: addValueForm.value.period,
actual_value: addValueForm.value.actual_value,
})
ElMessage.success(r.message || '已保存')
showAddValue.value = false
//
const kv: any = await api.get('/kpis/' + kpi.value.id)
values.value = kv.values || []
} catch (e: any) {
ElMessage.error(e?.response?.data?.detail || e?.message || '保存失败')
} finally {
addValueSaving.value = false
}
}
//
function formatValue(v: any) {
if (v === null || v === undefined || isNaN(Number(v))) return '--'