# KPI目标值多粒度改造（月/季/年分离）

> 需求提出：2026-08-17 | 提出人：任总（工作台使用中发现混淆）
> 文档版本：v1.0 | 状态：待评审
> 类型：后端改表 + 前端改造 + 数据清洗

## 一、问题描述

### 用户故事

作为CMA系统的操作人员，我在工作台看到"目标 1200"时，**无法判断这个目标是月度、季度还是年度**；当我点击进入KPI详情调整目标值时，**不知道该改的是月目标、季目标还是年目标**——系统只有一个单值 target_value，三个周期的目标混在一起，必然造成操作混淆。

### 现状痛点

```
① KPI定义的frequency字段：monthly 63个 / quarterly 11个 / weekly 2个 / half_year 10个
   → 定义了"考核频率"，但target_value是单值，没说清对应哪个周期

② target_value单值无法表达多周期目标：
   同一KPI（如F_REVENUE营收）：
     frequency=quarterly（季度考核）
     target_value=1200（单值）
     kpi_values.period=2026.06（月度数据！）
   → 1200到底是月目标？季目标？年度目标？三个信息互相矛盾

③ period格式混乱：
   2026.06 / 2025.1（缺零）/ 2026H1 / 2026-06 / 2021（年）
   → 前端排序、环比计算、图表展示不可靠
```

### 核心矛盾

```
考核频率（月/季/年）× 目标值（单值）× 实际数据周期（混合格式）
    ↓
三者不对齐 = 数据粒度不匹配 = 使用者必然混淆
```

## 二、解决方案

### 方案总览：目标值分级 + period格式化

```
① 数据库：kpi_definitions 增加三列
   target_monthly / target_quarterly / target_yearly

② 数据迁移：现有target_value按frequency归入对应列

③ 前端显示：按frequency显示对应目标值 + 周期标签

④ period格式统一：kpi_values.period 标准化为 YYYY-MM / YYYY-Qn / YYYY
```

## 三、功能列表

### 后端（backend）

- [ ] 1. `kpi_definitions` 表加3列（target_monthly / target_quarterly / target_yearly，decimal(15,2) 可空）
- [ ] 2. 数据迁移脚本：`UPDATE ... SET target_monthly=target_value WHERE frequency='monthly'`（quarterly/yearly同理）；weekly/half_year归入最接近周期（weekly→monthly，half_year→quarterly）并记录
- [ ] 3. API改造：KPI详情/列表接口返回 `target_monthly`、`target_quarterly`、`target_yearly` + `frequency`
- [ ] 4. 前端保存KPI时，按frequency写入对应目标列（如frequency=monthly则写target_monthly）
- [ ] 5. 新增period标准化工具脚本（清洗历史数据）

### 前端（frontend）

- [ ] 6. 工作台KPI卡：目标值旁显示周期标签"目标(月)"/"目标(季)"/"目标(年)"
- [ ] 7. KPI详情页"目标值"编辑：显示当前frequency对应的目标字段，明确标注周期
- [ ] 8. 历史数据tab：period统一展示格式（YYYY-MM）

### 数据（data）

- [ ] 9. 清洗kpi_values.period历史数据（2025.1→2025-01，2026H1→2026-H1，等）

## 四、数据流

```
展示流：
工作台/详情页 GET /kpis/:id
  → 返回 kpi + target_monthly/quarterly/yearly + frequency
  → 前端按frequency取对应目标值
  → 显示"目标(月): 18%" 或 "目标(季): 1200"

编辑流：
用户在详情页改目标值
  → 前端按frequency路由到对应字段（monthly→target_monthly）
  → PUT /kpis/:id { target_monthly: 20 }
  → 后端只更新该列，其他周期目标不受影响
```

## 五、界面设计

### 工作台KPI卡（改动）

```
┌─────────────────────────────────┐
│ 毛利率             [达标]        │
│ 18.5%   目标(月): 18%           │ ← 加频率标签
│ ████████████░░░░░               │
└─────────────────────────────────┘
```

### KPI详情页-基本信息（改动）

```
目标值(月度): [ 18 ] %    ← frequency=monthly时显示这个
目标值(季度): [     ]     ← 季度目标可另行填写
目标值(年度): [     ]     ← 年度目标可另行填写
```

## 六、验收标准

1. 工作台KPI卡显示带周期标签的目标值（如"目标(月): 18%"）
2. 月度KPI改目标只改target_monthly，季度/年度目标不受影响
3. frequency=quarterly的KPI（如F_REVENUE）工作台显示季度目标
4. kpi_values.period全部为标准格式（无2025.1、2026H1等异常格式）
5. 数据迁移后：原monthly的target_value已迁入target_monthly，无丢失
6. 一致性检查通过（consistency-check不报新错误）

## 七、工作量评估

| 项 | 内容 | 人天 |
|:--|:----|:---:|
| 后端 | 加列+迁移脚本+API改造 | 0.5 |
| 前端 | 工作台标签+详情页多周期目标 | 0.5 |
| 数据 | period清洗脚本+执行 | 0.3 |
| 测试 | 验收用例（多frequency验证） | 0.2 |
| **合计** | | **1.5天** |

## 八、关联模块

- 工作台（MyDashboard.vue）—— KPI卡显示
- KPI详情页（KPIDetail.vue）—— 目标值编辑
- KPI字典列表（KPIList.vue）—— 列表目标值列
- kpis.py API —— 目标值读写
- dashboard.py API —— my-dashboard返回
- 与"科目≠KPI"规范（kpi-account-governance-rule.md）配套：本需求解决"时间粒度"，前者解决"类型混用"

## 九、风险与注意

```
⚠️ 迁移不可逆：先备份kpi_definitions表（参考2026-08-17备份流程）
⚠️ weekly/half_year归并需人工确认映射规则
⚠️ period清洗会影响历史报表展示，需回归测试
⚠️ 前端所有"目标值"引用点需全局搜索（不止工作台和详情页）
```

## 十、执行分工建议

```
方案评审：研学（已分析）
需求文档：研学（本文档）
开发实施：项目Bot或全栈Bot（按此文档）
数据迁移：开发时一起做（备份先行）
验收：研学（按验收标准逐条验证，铁律七）
```
