# 疫苗接种数据填报 — 前端技术方案



> 依据：同目录功能需求、技术方案；交互对齐畜牧产品产量等村×年月填报；字段 **小驼峰**。



---



## 1. 页面与路由



| 项 | 说明 |

| --- | --- |

| **Vue 路径** | `ruoyi-ui/src/views/dataModel/vaccinationData/index.vue` |

| **组件名** | `VaccinationData` |

| **菜单配置** | 组件路径：`dataModel/vaccinationData/index` |

| **权限前缀** | `dataModel:vaccinationData:list\|query\|add\|edit\|remove\|import\|export` |



---



## 2. API 模块



| 项 | 说明 |

| --- | --- |

| **文件** | `ruoyi-ui/src/api/dataModel/vaccinationData.js` |

| **Base** | `/dataModel/vaccinationData` |



CRUD、`yearOptions` / `monthOptions` / `townOptions` / `villageTree`、导入 `importData`、模板 `importTemplate`、导出 `export`（可选 `townDeptId`）与同类村级填报模块同构；模板/导出均为 **GET + blob**。



| 方法 | 路径 | 说明 |

| --- | --- | --- |

| `listVaccinationData` | GET `/list` | 分页；筛选年、月、乡镇、村 |

| `getVaccinationData` | GET `/{id}` | 详情（含免疫率） |

| `addVaccinationData` | POST `/` | 新增 |

| `updateVaccinationData` | PUT `/` | 修改 |

| `delVaccinationData` | DELETE `/{ids}` | 删除 |

| `listVaccinationDataYearOptions` | GET `/yearOptions` | 年份下拉 |

| `listVaccinationDataMonthOptions` | GET `/monthOptions` | 月份下拉 |

| `listVaccinationDataTownOptions` | GET `/townOptions` | 乡镇下拉 |

| `listVaccinationDataVillageTree` | GET `/villageTree` | 县→乡镇→村树 |

| `importVaccinationData` | POST `/importData` | FormData：`file` + `statYear` + `statMonth` |

| `downloadVaccinationDataTemplate` | GET `/importTemplate` | 模板 blob |

| `exportVaccinationData` | GET `/export` | 参数：`statYear`、`statMonth`、可选 `townDeptId` |



---



## 3. 页面结构



1. **筛选**：年、月、乡镇、村（村为可搜索下拉，选项来自村树扁平化）。  

2. **列表**：年、月、乡镇、村、应免数、实免数、免疫率（`xx.xx%`）、操作。  

3. **新增/编辑**：选村（可搜索，标签「乡镇 / 村」）；新增默认本年本月；免疫率只读预览。  

4. **详情**：与表单同分区；含乡镇与免疫率；数量用 `formatWithUnit` 带「头」。  

5. **导入**：选年月 → upsert 摘要（insert/update/fail）；免疫率列由后端跳过；软警告弹窗展示。  

6. **导出**：选年月；所属乡镇与列表共用选项，打开时带入列表当前乡镇，清空=全部。



### 表单 / 查看分区



| 分区 | 内容 |

| --- | --- |

| 基本信息 | 年月、村（查看含乡镇） |

| 疫苗接种情况 | 应免数、实免数；只读免疫率；备注 |



---



## 4. 业务规则



| 规则 | 实现 |

| --- | --- |

| 唯一键 | 年 + 月 + 村（前端提交只传 `villageDeptId`；乡镇由后端反推） |

| 必填 | 年、月、村 |

| 数量 | 应免数、实免数：可选；非负整数；单位「头」；实免数 ≤ 应免数（前端） |

| 免疫率预览 | 应免数 &gt; 0 且实免数非空时：`(实免/应免)×100`，保留 2 位小数，展示为 `98.33%`；否则「—」 |

| 实免 &gt; 应免 | 新增/编辑表单拦截；导入仍由后端软警告（不阻断） |

| 不可未来月 | 表单 / 导入 / 导出校验 |



### 免疫率公式（与后端 `VaccinationDataDerivedSupport` 对齐）



```

immunityRate = round((actualVaccinateCount * 10000) / shouldVaccinateCount) / 100

```



前端仅作表单预览；落库与列表/详情以接口返回的 `immunityRate` 为准。



---



## 5. 国际化



`dataModel.vaccinationData`（`lang/zh|bo/dataModel.js`）；页面 `dmNs = 'vaccinationData'`，复用 `dataModelLocaleMixin`（`dmT` / `dmCommon` / `formatWithUnit`）。查看表单使用 `dm-view-form` 高亮。



---



## 6. 联调说明



1. 执行 `sql/biz_vaccination_data.sql`。  

2. 菜单组件 `dataModel/vaccinationData/index`，权限见 §1。  

3. 验证：新增默认年月、免疫率只读预览与保存后一致、列表筛选村、导出乡镇带入列表筛选、实免&gt;应免拦截、导入 upsert。



---



## 7. 文件清单



| 类型 | 路径 |

| --- | --- |

| 页面 | `ruoyi-ui/src/views/dataModel/vaccinationData/index.vue` |

| API | `ruoyi-ui/src/api/dataModel/vaccinationData.js` |

| i18n | `lang/zh/dataModel.js`、`lang/bo/dataModel.js` → `vaccinationData` |

| 前端技术方案 | 本文档 |



---



## 8. 修订记录



| 版本 | 说明 |

| --- | --- |

| 1.0 | 初版：村×年月；CRUD + upsert 导入 + 导出乡镇与列表联动；免疫率前端预览 |
| 1.1 | 实免数须 ≤ 应免数（仅前端表单校验） |


