西藏巴青项目

牦牛出栏数据填报技术方案.md 11KB

牦牛出栏数据填报 — 技术方案

依据:同目录 牦牛出栏数据填报功能需求.md;模板 E:\luhao\工作交接\巴青项目\农牧数据\农业农村和科技水利局-业务办\牲畜数据.xlsx6 个 Sheet(2026 年度出栏及自食统计表)。


1. 技术架构

说明
后端 RuoYi v3.9.2(springboot2):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid
数据库 MySQL 5.7.39,InnoDB,utf8mb4
前端 若依 Vue2 + Element UI
Excel Apache POI(与「牦牛存栏数据填报」一致)
组织 sys_dept 乡镇字典;复用 TownDeptSupport

分层BizYakOutboundReportControllerIBizYakOutboundReportServiceBizYakOutboundReportMapperdomain;Excel 由 YakOutboundReportExcelParser(导入解析)、YakOutboundReportExcelExporter(按年导出)承担。

代码位置baqing-admincom.ruoyi.web.modules.industryservice(与产业数据模型同包)。

模板文件baqing-admin/src/main/resources/templates/yak_outbound_report_import_template.xlsx(导入、导出、下载模板共用)。

参考实现BizYakHerdInventory*YakHerdInventoryExcelParserTownDeptSupport(存栏填报模块,模式一致)。


2. 数据库设计

2.1 表 biz_yak_outbound_report(牦牛出栏数据填报)

字段 类型 非空 说明
id bigint(20) Y 主键
stat_year int(11) Y 所属年份(自然年)
town_dept_id bigint(20) Y 所属乡镇,sys_dept.dept_id
town_name varchar(64) Y 乡镇名称冗余
farmer_household_count int(11) N 农牧户户数
farmer_population_count int(11) N 农牧户人数
yak_outbound_count int(11) N 牦牛出栏数(头)
cattle_outbound_count int(11) N 黄牛/奶牛/犏牛出栏数(头)
sheep_outbound_count int(11) N 绵羊出栏数(只)
goat_outbound_count int(11) N 山羊出栏数(只)
horse_mule_outbound_count int(11) N 马骡出栏数(匹)
donkey_outbound_count int(11) N 驴出栏数(头)
self_consumption_cattle_count int(11) N 自食牛头数(头)
self_consumption_sheep_count int(11) N 自食绵羊只数(只)
self_consumption_goat_count int(11) N 自食山羊只数(只)
create_by / create_time 审计
update_by / update_time 审计
remark varchar(500) N 备注

说明:本表不使用逻辑删除,无 del_flag;删除为物理 DELETE

索引与约束

  • UNIQUE uk_year_town (stat_year, town_dept_id) — 年份+乡镇唯一,支撑导入 upsert。
  • KEY idx_stat_year (stat_year)
  • KEY idx_town_dept_id (town_dept_id)

DDL 文件sql/biz_yak_outbound_report.sql

2.2 乡镇字典(复用)

SELECT dept_id, dept_name, order_num
FROM sys_dept
WHERE parent_id = 100
  AND order_num > 12
  AND del_flag = '0'
  AND status = '0'
ORDER BY order_num;

封装:TownDeptSupport.listReportTowns()requireReportTown(deptId)

乡镇别名(导入):模板「扎色镇」→ sys_dept「杂色镇」,在 YakOutboundReportExcelParser.resolveTownDeptIdTownDeptSupport 扩展 normalizeTownName

2.3 可选年份

与存栏模块一致:YakOutboundReportYearSupport 或复用 YakHerdInventoryYearSupport 逻辑,返回当前年起向前 5 年共 6 个年份。


3. 接口设计

Base Path/dataModel/yakOutboundReport

权限前缀dataModel:yakOutboundReport

# 说明 Method URI 权限
3.1 分页列表 GET /list list
3.2 详情 GET /{id} query
3.3 新增 POST / add
3.4 修改 PUT / edit
3.5 删除 DELETE /{ids} remove
3.6 乡镇下拉 GET /townOptions list
3.7 年份下拉 GET /yearOptions list
3.8 导入 POST /importData import
3.9 下载导入模板 GET /importTemplate import
3.10 按年份导出 GET /export export

3.1.1 列表 Query

参数 类型 说明
pageNum / pageSize int 默认 1 / 20
statYear int 所属年份,精确
townDeptId long 所属乡镇 dept_id,精确

列表 VO

列标题 字段
所属年份 statYear
所属乡镇 townName
农牧户户数 farmerHouseholdCount
农牧户人数 farmerPopulationCount
牦牛出栏数 yakOutboundCount
自食情况(牛) selfConsumptionCattleCount

3.2.1 详情

返回需求 §5.5 指定字段(驼峰):

statYeartownNamefarmerHouseholdCountfarmerPopulationCountyakOutboundCountselfConsumptionCattleCount

可选附带 idtownDeptId 供前端跳转修改。

3.3.1 新增/修改 Body

字段 必填 校验
statYear Y yearOptions 范围内
townDeptId Y 须在乡镇字典内
farmerHouseholdCount 等数量字段 N >= 0 整数
id 修改必填

唯一性(手工新增)countByYearAndTownExcludeId > 0 则拒绝。导入走 upsert。

3.5.1 删除

DELETE FROM biz_yak_outbound_report WHERE id IN (...),物理删除。

3.8 导入

请求multipart/form-data

参数 必填 说明
file Y .xlsx
statYear Y 填报年份

UpsertBizYakOutboundReportServiceImpl.upsertImportRow):

  1. selectByYearAndTown(statYear, townDeptId)
  2. 无记录 → insert;有记录 → update 全字段覆盖

响应 datainsertCountupdateCountfailCountfailMessageswarnMessages(自食大于出栏等)

3.8.1 Excel 第 6 Sheet 解析约定

约定
Sheet workbook.getSheetAt(5)(第 6 个 Sheet,0-based 索引 5)
表头识别 扫描含「乡镇」且同行含「户数」「牦牛」的行;数据自 headerRow + 1
终止行 乡镇为空,或乡镇名为「合计」
列映射(0-based)
列号 实体字段
1 乡镇 → townDeptId / townName
2 farmerHouseholdCount
3 farmerPopulationCount
4 yakOutboundCount
5 cattleOutboundCount
6 sheepOutboundCount
7 goatOutboundCount
8 horseMuleOutboundCount
9 donkeyOutboundCount
10 跳过(出栏小计)
11 selfConsumptionCattleCount
12 selfConsumptionSheepCount
13 selfConsumptionGoatCount
14 跳过(自食小计)
15 remark

模板存在合并单元格,部分行 POI 读列可能错位;解析器宜按表头行固定列号读取,并对空单元格按 0 或 null 处理(与存栏导入一致)。

导入事务:逐乡镇独立处理,单乡镇失败不影响其余。

3.10 按年份导出

请求GET /export?statYear=2026

参数 必填 说明
statYear Y 导出年份,须在 yearOptions 范围内

响应application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 文件流;文件名 {statYear}年牦牛出栏数据.xlsx

实现BizYakOutboundReportServiceImpl.exportByYearYakOutboundReportExcelExporter.export

  1. 加载 classpath 模板 YakOutboundReportExcelExporter.TEMPLATE_CLASSPATH
  2. 解析出栏 Sheet(YakOutboundReportExcelParser.resolveSheet
  3. 替换表头中的四位年份为 statYear(含标题行与「年牲畜出栏数」表头区块;年份与「年」之间允许空格)
  4. 将 Sheet 名称更新为 {年份后两位}年出栏(如 2024 → 24年出栏
  5. 查询 stat_year = statYear 的全部记录,按 town_dept_id 建 Map
  6. 遍历 TownDeptSupport.listReportTowns(),逐乡镇写行;无数据则仅写乡镇名
  7. 末行写「合计」,对已填报乡镇数值列求和;K/O 列写入出栏/自食小计

与 3.9 区别/importTemplate 返回空白模板;/export 返回填充后的全县报表。


4. 前端设计(要点)

说明
路径 ruoyi-ui/src/views/dataModel/yakOutboundReport/index.vue
API ruoyi-ui/src/api/dataModel/yakOutboundReport.js
列表 年份、乡镇筛选;列:所属年份、所属乡镇、农牧户户数、农牧户人数、牦牛出栏数、自食情况(牛)
详情 对话框只读,展示 §5.5 六字段
表单 新增/修改展示全部数量字段;年份/乡镇下拉;el-input-number :min="0" :precision="0"
导入 先选「填报年份」→ 上传 → 展示导入结果摘要
模板下载 GET /importTemplate;空白模板
按年份导出 列表先选「所属年份」→ GET /exportdownload('dataModel/yakOutboundReport/export', { statYear })

5. 菜单与权限(示例)

类型 名称 权限标识
菜单 牦牛出栏数据填报 dataModel:yakOutboundReport:list
按钮 查询 dataModel:yakOutboundReport:query
按钮 新增 dataModel:yakOutboundReport:add
按钮 修改 dataModel:yakOutboundReport:edit
按钮 删除 dataModel:yakOutboundReport:remove
按钮 导入 dataModel:yakOutboundReport:import
按钮 导出 dataModel:yakOutboundReport:export

挂载目录:产业数据模型及服务。菜单 SQL:sql/biz_sys_menu_yak_outbound_report.sql(实施阶段)。


6. 与存栏填报模块的关系

模块 模板 Sheet 业务含义
牦牛存栏数据填报 biz_yak_herd_inventory 牲畜数据.xlsx 第 1 Sheet(畜群结构) 年末存栏结构
牦牛出栏数据填报 biz_yak_outbound_report 牲畜数据.xlsx 第 6 Sheet 年度出栏及自食

两模块共用 TownDeptSupport、年份范围规则、导入 upsert 模式;本期不实现跨表校验(如出栏数不大于存栏数)。


7. 交付清单

  • sql/biz_yak_outbound_report.sql
  • BizYakOutboundReport Domain / Mapper / XML / Service / Controller
  • YakOutboundReportExcelParser + YakOutboundReportExcelExporter + 导入模板 xlsx(第 6 Sheet)
  • 复用 TownDeptSupport、年份 Support
  • 前端列表/表单/导入/导出
  • 单元测试 + 接口测试
  • sql/biz_sys_menu_yak_outbound_report.sql

8. 修订记录

版本 说明
1.0 初稿:表结构、CRUD、第 6 Sheet 导入、物理删除、乡镇字典
1.1 实现按年份导出全县乡镇 Excel;YakOutboundReportExcelExporter