依据:同目录
牦牛出栏数据填报功能需求.md;模板E:\luhao\工作交接\巴青项目\农牧数据\农业农村和科技水利局-业务办\牲畜数据.xlsx第 6 个 Sheet(2026 年度出栏及自食统计表)。
| 项 | 说明 |
|---|---|
| 后端 | 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 |
分层:BizYakOutboundReportController → IBizYakOutboundReportService → BizYakOutboundReportMapper → domain;Excel 由 YakOutboundReportExcelParser(导入解析)、YakOutboundReportExcelExporter(按年导出)承担。
代码位置:baqing-admin → com.ruoyi.web.modules.industryservice(与产业数据模型同包)。
模板文件:baqing-admin/src/main/resources/templates/yak_outbound_report_import_template.xlsx(导入、导出、下载模板共用)。
参考实现:BizYakHerdInventory*、YakHerdInventoryExcelParser、TownDeptSupport(存栏填报模块,模式一致)。
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
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.resolveTownDeptId 或 TownDeptSupport 扩展 normalizeTownName。
与存栏模块一致:YakOutboundReportYearSupport 或复用 YakHerdInventoryYearSupport 逻辑,返回当前年起向前 5 年共 6 个年份。
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 |
| 参数 | 类型 | 说明 |
|---|---|---|
pageNum / pageSize |
int | 默认 1 / 20 |
statYear |
int | 所属年份,精确 |
townDeptId |
long | 所属乡镇 dept_id,精确 |
列表 VO
| 列标题 | 字段 |
|---|---|
| 所属年份 | statYear |
| 所属乡镇 | townName |
| 农牧户户数 | farmerHouseholdCount |
| 农牧户人数 | farmerPopulationCount |
| 牦牛出栏数 | yakOutboundCount |
| 自食情况(牛) | selfConsumptionCattleCount |
返回需求 §5.5 指定字段(驼峰):
statYear、townName、farmerHouseholdCount、farmerPopulationCount、yakOutboundCount、selfConsumptionCattleCount
可选附带 id、townDeptId 供前端跳转修改。
| 字段 | 必填 | 校验 |
|---|---|---|
statYear |
Y | 在 yearOptions 范围内 |
townDeptId |
Y | 须在乡镇字典内 |
farmerHouseholdCount 等数量字段 |
N | >= 0 整数 |
id |
修改必填 | — |
唯一性(手工新增):countByYearAndTownExcludeId > 0 则拒绝。导入走 upsert。
DELETE FROM biz_yak_outbound_report WHERE id IN (...),物理删除。
请求:multipart/form-data
| 参数 | 必填 | 说明 |
|---|---|---|
file |
Y | .xlsx |
statYear |
Y | 填报年份 |
Upsert(BizYakOutboundReportServiceImpl.upsertImportRow):
selectByYearAndTown(statYear, townDeptId)insert;有记录 → update 全字段覆盖响应 data:insertCount、updateCount、failCount、failMessages、warnMessages(自食大于出栏等)
| 项 | 约定 |
|---|---|
| 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 处理(与存栏导入一致)。
导入事务:逐乡镇独立处理,单乡镇失败不影响其余。
请求:GET /export?statYear=2026
| 参数 | 必填 | 说明 |
|---|---|---|
statYear |
Y | 导出年份,须在 yearOptions 范围内 |
响应:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 文件流;文件名 {statYear}年牦牛出栏数据.xlsx。
实现:BizYakOutboundReportServiceImpl.exportByYear → YakOutboundReportExcelExporter.export:
YakOutboundReportExcelExporter.TEMPLATE_CLASSPATHYakOutboundReportExcelParser.resolveSheet)statYear(含标题行与「年牲畜出栏数」表头区块;年份与「年」之间允许空格){年份后两位}年出栏(如 2024 → 24年出栏)stat_year = statYear 的全部记录,按 town_dept_id 建 MapTownDeptSupport.listReportTowns(),逐乡镇写行;无数据则仅写乡镇名与 3.9 区别:/importTemplate 返回空白模板;/export 返回填充后的全县报表。
| 项 | 说明 |
|---|---|
| 路径 | 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 /export;download('dataModel/yakOutboundReport/export', { statYear }) |
| 类型 | 名称 | 权限标识 |
|---|---|---|
| 菜单 | 牦牛出栏数据填报 | 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(实施阶段)。
| 模块 | 表 | 模板 Sheet | 业务含义 |
|---|---|---|---|
| 牦牛存栏数据填报 | biz_yak_herd_inventory |
牲畜数据.xlsx 第 1 Sheet(畜群结构) |
年末存栏结构 |
| 牦牛出栏数据填报 | biz_yak_outbound_report |
牲畜数据.xlsx 第 6 Sheet |
年度出栏及自食 |
两模块共用 TownDeptSupport、年份范围规则、导入 upsert 模式;本期不实现跨表校验(如出栏数不大于存栏数)。
sql/biz_yak_outbound_report.sqlBizYakOutboundReport Domain / Mapper / XML / Service / ControllerYakOutboundReportExcelParser + YakOutboundReportExcelExporter + 导入模板 xlsx(第 6 Sheet)TownDeptSupport、年份 Supportsql/biz_sys_menu_yak_outbound_report.sql| 版本 | 说明 |
|---|---|
| 1.0 | 初稿:表结构、CRUD、第 6 Sheet 导入、物理删除、乡镇字典 |
| 1.1 | 实现按年份导出全县乡镇 Excel;YakOutboundReportExcelExporter |