# 草场管理 — 技术方案

> 依据：同目录 `草场管理功能需求.md`。草场台账 **CRUD** + **逻辑删除**；**不含**地图标点、附件上传。

---

## 1. 技术架构

| 项 | 说明 |
| --- | --- |
| **后端** | RuoYi **v3.9.2**（**springboot2** 分支）：JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| **数据库** | MySQL **5.7.39**，InnoDB，`utf8mb4` |
| **前端** | 若依 Vue2（本方案不展开页面实现） |

**分层**：`Controller`（`@PreAuthorize`、`AjaxResult` / `TableDataInfo`）→ `Service`（`GrasslandValidation` 业务校验）→ `Mapper`/XML → `domain`。

**代码位置（建议）**：`baqing-admin` → `com.ruoyi.web.modules.industryservice`（与「牧场管理」同模块：`BizGrassland`、Mapper、Service、Controller）。

**业务摘要**

| 场景 | 行为 |
| --- | --- |
| 新增 | 校验 **§3.5**；`del_flag='0'` |
| 修改 | 全字段可改；重新校验；`update` 带 `del_flag='0'` 条件 |
| 列表/详情 | 仅 `del_flag='0'`；排序 `create_time DESC, id DESC` |
| 删除 | **逻辑删除**：`del_flag` 置 `'2'`（若依惯例） |

---

## 2. 数据库设计

### 2.1 表 `biz_grassland`（草场）

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `grassland_name` | `varchar(32)` | Y | — | 草场名称（需求 **1～10** 字） |
| `area_mu` | `decimal(12,2)` | Y | — | 面积（**亩**），> 0 |
| `grazing_ban_area` | `decimal(12,2)` | N | NULL | 禁牧面积（**亩**），有值须 > 0 |
| `grass_balance_area` | `decimal(12,2)` | N | NULL | 草畜平衡面积（**亩**），有值须 > 0 |
| `degradation_level` | `tinyint(4)` | N | NULL | 退化等级 **§2.2** |
| `utilization_type` | `tinyint(4)` | N | NULL | 利用类型 **§2.2** |
| `grass_yield_per_mu` | `decimal(12,2)` | N | NULL | 亩产草量（**kg/亩**），有值须 > 0 |
| `utilization_rate` | `decimal(5,4)` | N | NULL | 利用率 **0～1**（闭区间） |
| `grazing_ban_start_date` | `date` | N | NULL | 禁牧开始日期（与结束成对） |
| `grazing_ban_end_date` | `date` | N | NULL | 禁牧结束日期；有值时 ≥ 开始日 |
| `rotation_plot_count` | `int(11)` | N | NULL | 轮牧小区数量（**块**），有值须 ≥ 1 |
| `rotation_grazing_days` | `int(11)` | N | NULL | 小区放牧天数（**天**），有值须 ≥ 1 |
| `rotation_cycle_days` | `int(11)` | N | NULL | 轮牧周期（**天**），有值须 ≥ 1 |
| `del_flag` | `char(1)` | Y | `'0'` | `0` 存在 `2` 删除 |
| `create_by` / `create_time` / `update_by` / `update_time` | 若依惯例 | — | — | 审计 |
| `remark` | `varchar(200)` | N | NULL | 备注（≤100 字） |

**索引**：`PRIMARY KEY (id)`；`KEY idx_grassland_name (grassland_name)`；`KEY idx_utilization_type (utilization_type)`；`KEY idx_degradation_level (degradation_level)`；`KEY idx_create_time (create_time)`；`KEY idx_del_flag (del_flag)`。

**DDL（MySQL 5.7）**：见 `sql/biz_grassland.sql`；已有库升级见 `sql/biz_grassland_fields_alter.sql`。
### 2.2 枚举常量

| 字段 | 值 | 含义 |
| --- | --- | --- |
| `degradation_level` | `1` | 未退化 |
| | `2` | 轻度 |
| | `3` | 中度 |
| | `4` | 重度 |
| | `5` | 极重度 |
| `utilization_type` | `1` | 禁牧 |
| | `2` | 轮牧 |
| | `3` | 全年放牧 |
| `del_flag` | `0` | 正常 |
| | `2` | 已逻辑删除 |

---

## 3. 接口设计

**统一响应**：`AjaxResult`（`code` / `msg` / `data`）或分页 `TableDataInfo`（`rows`、`total`）。

**权限标识**：`dataModel:grassland:list|query|add|edit|remove|export`

**Base Path**：`/dataModel/grassland`

| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 3.1 | 分页列表 | GET | `/dataModel/grassland/list` | `dataModel:grassland:list` | Query **3.1.1**；`del_flag='0'`；`create_time DESC, id DESC` |
| 3.2 | 详情 | GET | `/dataModel/grassland/{id}` | `dataModel:grassland:query` | 全字段；`del_flag='0'`，否则无数据 |
| 3.3 | 新增 | POST | `/dataModel/grassland` | `dataModel:grassland:add` | Body **3.3.1**；`del_flag='0'` |
| 3.4 | 修改 | PUT | `/dataModel/grassland` | `dataModel:grassland:edit` | Body 含 `id`；全量校验 |
| 3.5 | 删除 | DELETE | `/dataModel/grassland/{ids}` | `dataModel:grassland:remove` | 逻辑删除；`ids` 逗号分隔批量 |

#### 3.1.1 列表 Query

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `pageNum` / `pageSize` | int | N | 默认 `1` / `20` |
| `keyword` | string | N | 草场名称**模糊**；空不过滤 |
| `utilizationType` | int | N | `1`～`3` **精确**；空不过滤 |
| `degradationLevel` | int | N | `1`～`5` **精确**（可选扩展筛选项）；空不过滤 |

#### 3.3.1 新增 / 修改 Body（驼峰）

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `id` | 修改 Y | 主键 |
| `grasslandName` | Y | 1～10 字符 |
| `areaMu` | Y | 正数（亩） |
| `grazingBanArea` | N | 正数（亩）；空不校验 |
| `grassBalanceArea` | N | 正数（亩）；空不校验 |
| `degradationLevel` | N | `1`～`5`；空不校验 |
| `utilizationType` | N | `1`～`3`；空不校验 |
| `grassYieldPerMu` | N | 正数（kg/亩）；空不校验 |
| `utilizationRate` | N | `0`～`1`（含端点）；空不校验 |
| `grazingBanStartDate` | N | `yyyy-MM-dd`；与结束成对 |
| `grazingBanEndDate` | N | `yyyy-MM-dd`；有值时 ≥ `grazingBanStartDate` |
| `rotationPlotCount` | N | 正整数（块）；空不校验 |
| `rotationGrazingDays` | N | 正整数（天）；空不校验 |
| `rotationCycleDays` | N | 正整数（天）；空不校验 |
| `remark` | N | ≤100 字 |

**列表行字段（示例）**：`id`、`grasslandName`、`areaMu`、`grazingBanArea`、`grassBalanceArea`、`degradationLevel`、`utilizationType`、`grassYieldPerMu`、`utilizationRate`、`grazingBanStartDate`、`grazingBanEndDate`、`rotationPlotCount`、`rotationGrazingDays`、`rotationCycleDays`、`createTime`。

**日期序列化**：JSON 使用 `yyyy-MM-dd`；与若依 `JsonFormat` / 全局 Jackson 配置一致。

### 3.4 Mapper 约定

- 列表、详情、更新：`and del_flag = '0'`。  
- 逻辑删除：`update biz_grassland set del_flag='2', update_by=?, update_time=now() where del_flag='0' and id in (...)`。  
- 删除前查询可用 `selectByIdAny`（不过滤 `del_flag`），用于审计或幂等。

### 3.5 服务端校验（摘要）

| 项 | 规则 |
| --- | --- |
| 草场名称 | **必填**；1～10 字符 |
| 面积 | **必填**；> 0 |
| 禁牧面积 / 草畜平衡面积 | 选填；有值须 > 0 |
| 退化等级 | 选填；有值 ∈ {1, 2, 3, 4, 5} |
| 利用类型 | 选填；有值 ∈ {1, 2, 3} |
| 亩产草量 | 选填；有值须 > 0 |
| 利用率 | 选填；有值 0 ≤ x ≤ 1 |
| 禁牧日期 | 选填；同时有值或同时为空；有值时 `start ≤ end` |
| 轮牧三项 | 选填；有值均为 ≥ 1 的整数 |
| 备注 | 可空；有值 ≤100 字 |

校验类建议：`GrasslandRules`（枚举常量）、`GrasslandValidation`（`validateRowForSave`）。

---

## 4. 菜单与权限（示例）

| 类型 | 名称 | 权限标识 |
| --- | --- | --- |
| 菜单 | 草场管理 | `dataModel:grassland:list` |
| 按钮 | 查询 | `dataModel:grassland:query` |
| 按钮 | 新增 | `dataModel:grassland:add` |
| 按钮 | 修改 | `dataModel:grassland:edit` |
| 按钮 | 删除 | `dataModel:grassland:remove` |
| 按钮 | 导出 | `dataModel:grassland:export` |

组件路径建议：`dataModel/grassland/index`（菜单挂载在「产业数据模型及体系」下）。

---

## 5. 交付清单

- [ ] `sql/biz_grassland.sql`、菜单与按钮权限 SQL  
- [ ] `BizGrassland` Domain / Mapper / XML / Service / Controller  
- [ ] `GrasslandRules`、`GrasslandValidation`  
- [ ] 逻辑删除  
- [ ] 单元测试 / 接口测试（MockMvc）  

---

## 6. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：对齐功能需求；`biz_grassland`；逻辑删除 `del_flag`；无地图与附件接口 |
| 1.1 | 新增禁牧面积、草畜平衡面积；除名称与面积外字段改为可空/选填 |
