# Results Overview Risk Model Linkage Frontend Implementation Plan

> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [x]`) syntax for tracking.

**Goal:** 将结果总览模型区接入真实接口，支持多卡片联动、任意触发/同时触发切换、员工姓名或工号与部门筛选，以及异常标签展示。

**Architecture:** 保持 `PreliminaryCheck.vue` 作为结果总览页面主入口，不新增路由或二级页面。模型卡片接口与人员列表接口分开请求，`RiskModelSection.vue` 内统一维护卡片选择、匹配模式、关键词、部门和分页状态，列表按状态组合查询。

**Tech Stack:** Vue 2, Element UI, Axios (`@/utils/request`), Node.js

---

### Task 1: 补模型区 API 封装

**Files:**
- Modify: `ruoyi-ui/src/api/ccdi/projectOverview.js`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-api.test.js`

- [x] **Step 1: Write the failing test**

新增接口静态断言，锁定以下方法与路径：

- `getOverviewRiskModelCards`
- `getOverviewRiskModelPeople`
- `/ccdi/project/overview/risk-models/cards`
- `/ccdi/project/overview/risk-models/people`
- `matchMode`

- [x] **Step 2: Run test to verify it fails**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-api.test.js
```

Expected:

- `FAIL`

- [x] **Step 3: Write minimal implementation**

在 API 模块中新增：

- `getOverviewRiskModelCards(projectId)`
- `getOverviewRiskModelPeople(params)`

列表接口需透传：

- `projectId`
- `modelCodes`
- `matchMode`
- `keyword`
- `deptId`
- `pageNum`
- `pageSize`

- [x] **Step 4: Run test to verify it passes**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-api.test.js
```

Expected:

- `PASS`

- [x] **Step 5: Commit**

```bash
git add ruoyi-ui/src/api/ccdi/projectOverview.js ruoyi-ui/tests/unit/preliminary-check-model-api.test.js
git commit -m "补充结果总览模型区前端接口封装"
```

### Task 2: 在入口页接入模型区真实数据

**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue`
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-data-loading.test.js`

- [x] **Step 1: Write the failing test**

新增入口页静态断言，要求：

- `PreliminaryCheck.vue` 引入 `getOverviewRiskModelCards`
- 模型区真实数据不再只依赖旧 mock
- 页面仍保留 `loading / empty / loaded` 状态结构

- [x] **Step 2: Run test to verify it fails**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-data-loading.test.js
```

Expected:

- `FAIL`

- [x] **Step 3: Write minimal implementation**

在 `PreliminaryCheck.vue` 中：

- 拉取模型卡片真实数据
- 将模型区交给 `RiskModelSection.vue` 内部继续请求列表接口
- 清理 `preliminaryCheck.mock.js` 中模型区旧的 `warningTypeOptions`、旧 `filterValues.model` 依赖
- 保留空态 mock 作为兜底展示结构，不新增业务逻辑兜底

- [x] **Step 4: Run test to verify it passes**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-data-loading.test.js
```

Expected:

- `PASS`

- [x] **Step 5: Commit**

```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js ruoyi-ui/tests/unit/preliminary-check-model-data-loading.test.js
git commit -m "接入结果总览模型卡片真实数据"
```

### Task 3: 改造模型卡片多选与触发方式切换

**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-multiselect.test.js`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-match-mode.test.js`

- [x] **Step 1: Write the failing test**

新增组件静态/行为断言，锁定：

- 卡片支持多选
- 再次点击已选卡片可取消
- 存在 `matchMode`
- 页面出现“任意触发”“同时触发”文案

- [x] **Step 2: Run test to verify it fails**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-multiselect.test.js
node tests/unit/preliminary-check-model-match-mode.test.js
```

Expected:

- `FAIL`

- [x] **Step 3: Write minimal implementation**

在 `RiskModelSection.vue` 中新增状态：

- `selectedModelCodes`
- `matchMode`
- `keyword`
- `deptId`
- `pageNum`
- `pageSize`
- `cardLoading`
- `tableLoading`

交互规则：

- 默认 `selectedModelCodes = []`
- 默认 `matchMode = "ANY"`
- 选中多张卡片时允许切换 `ANY / ALL`
- 不选卡片或仅选一张时，切换模式不报错，仍按当前接口语义请求

- [x] **Step 4: Run test to verify it passes**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-multiselect.test.js
node tests/unit/preliminary-check-model-match-mode.test.js
```

Expected:

- `PASS`

- [x] **Step 5: Commit**

```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue ruoyi-ui/tests/unit/preliminary-check-model-multiselect.test.js ruoyi-ui/tests/unit/preliminary-check-model-match-mode.test.js
git commit -m "补充结果总览模型卡片联动交互"
```

### Task 4: 替换筛选条与人员列表列

**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-filters.test.js`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-table-columns.test.js`

- [x] **Step 1: Write the failing test**

锁定以下变更：

- 删除“筛查模型”
- 删除“预警类型”
- 新增“员工姓名或工号”
- 新增“部门”
- 新增“任意触发”“同时触发”
- 删除“预警类型”列
- 新增“工号”列
- 新增“异常标签”列

- [x] **Step 2: Run test to verify it fails**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-filters.test.js
node tests/unit/preliminary-check-model-table-columns.test.js
```

Expected:

- `FAIL`

- [x] **Step 3: Write minimal implementation**

在筛选区：

- 保留 `查询 / 重置`
- 关键词输入框支持姓名或工号
- 部门优先复用仓库现有部门选项接口
- 重置时恢复：
  - `selectedModelCodes = []`
  - `matchMode = "ANY"`
  - `keyword = ""`
  - `deptId = undefined`
  - `pageNum = 1`

在表格列：

- 删除 `warningType`
- 增加 `staffCode`
- `modelNames` 显示当前上下文模型名称摘要
- `hitTagList` 用 `el-tag` 展示 `ruleName`
- 颜色映射复用 `DetailQuery.vue` 风险等级映射方式

- [x] **Step 4: Run test to verify it passes**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-filters.test.js
node tests/unit/preliminary-check-model-table-columns.test.js
```

Expected:

- `PASS`

- [x] **Step 5: Commit**

```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue ruoyi-ui/tests/unit/preliminary-check-model-filters.test.js ruoyi-ui/tests/unit/preliminary-check-model-table-columns.test.js
git commit -m "调整结果总览模型区筛选与列表列"
```

### Task 5: 前端联调验证与实施记录

**Files:**
- Modify: `ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js`
- Create: `ruoyi-ui/tests/unit/preliminary-check-model-linkage-flow.test.js`
- Modify: `docs/plans/frontend/2026-03-20-results-overview-risk-model-linkage-frontend-implementation.md`
- Create: `docs/tests/records/2026-03-20-results-overview-risk-model-linkage-frontend-verification.md`
- Create: `docs/reports/implementation/2026-03-20-results-overview-risk-model-linkage-frontend-implementation.md`

- [x] **Step 1: Write linkage flow assertions**

覆盖以下联动流：

- 默认全部模型
- 选中一张卡片
- 同时选中多张卡片 + `ANY`
- 同时选中多张卡片 + `ALL`
- 取消部分卡片
- 全部取消恢复默认
- 关键词 + 部门 + 多卡片叠加

- [x] **Step 2: Run final frontend verification**

Run:

```bash
cd ruoyi-ui
node tests/unit/preliminary-check-model-api.test.js
node tests/unit/preliminary-check-model-data-loading.test.js
node tests/unit/preliminary-check-model-multiselect.test.js
node tests/unit/preliminary-check-model-match-mode.test.js
node tests/unit/preliminary-check-model-filters.test.js
node tests/unit/preliminary-check-model-table-columns.test.js
node tests/unit/preliminary-check-model-linkage-flow.test.js
```

Expected:

- `PASS`

- [x] **Step 3: Write verification and implementation records**

记录：

- 模型区真实接口接入
- 多卡片联动
- 任意触发 / 同时触发切换
- 关键词、部门、分页联动验证

- [x] **Step 4: Commit**

```bash
git add ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js ruoyi-ui/tests/unit/preliminary-check-model-linkage-flow.test.js docs/plans/frontend/2026-03-20-results-overview-risk-model-linkage-frontend-implementation.md docs/tests/records/2026-03-20-results-overview-risk-model-linkage-frontend-verification.md docs/reports/implementation/2026-03-20-results-overview-risk-model-linkage-frontend-implementation.md
git commit -m "补充结果总览模型区前端实施记录"
```
