# 牧场管理 — 技术方案

> 依据：同目录 `牧场管理功能需求.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；照片上传复用 `POST /common/upload` |
| **区划** | 省 / 市 / 县三级级联；码表来源与项目行政区划组件一致（国标码或内置树） |

**分层**：`Controller`（权限、`AjaxResult` / `TableDataInfo`）→ `Service`（校验、证件联动、删旧照片）→ `Mapper`/XML → `domain`。

**代码位置（建议）**：`baqing-admin` → `com.ruoyi.web.modules.datamodel`（`BizPasture`、Mapper、Service、Controller）。

**业务摘要**

| 场景 | 行为 |
| --- | --- |
| 新增 | 校验必填；`biz_status` 缺省 `1`（正常）；`del_flag=0` |
| 修改 | 全字段可改；`pasture_nature` 变更时重校 `id_card_no`；换照片删旧 `photo_file_path` |
| 列表/详情 | `del_flag=0`；排序 `create_time DESC, id DESC`；可按角色脱敏身份证/手机 |
| 删除 | **逻辑删除**：`del_flag` 置 `2`（若依惯例）；删照片物理文件（与产品约定一致） |

---

## 2. 数据库设计

### 2.1 表 `biz_pasture`（牧场 / 养殖主体）

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `pasture_name` | `varchar(32)` | Y | — | 牧场名称（需求 **1～10** 字） |
| `pasture_nature` | `tinyint(4)` | Y | — | `1` 个体 `2` 企业 |
| `id_card_no` | `varchar(32)` | Y | — | 身份证号 / 主体识别号（统一存） |
| `province_code` | `varchar(12)` | Y | — | 省级区划码 |
| `province_name` | `varchar(64)` | Y | — | 省名称 |
| `city_code` | `varchar(12)` | Y | — | 市级区划码 |
| `city_name` | `varchar(64)` | Y | — | 市名称 |
| `county_code` | `varchar(12)` | Y | — | 县级区划码 |
| `county_name` | `varchar(64)` | Y | — | 县（区）名称 |
| `detail_address` | `varchar(100)` | N | NULL | 详细地址（≤50 字） |
| `person_in_charge` | `varchar(32)` | N | NULL | 负责人（≤10 字） |
| `contact_phone` | `varchar(20)` | Y | — | 联系方式（手机号） |
| `biz_status` | `tinyint(4)` | Y | `1` | `1` 正常 `2` 停业 `3` 注销 |
| `photo_file_url` | `varchar(512)` | N | NULL | 照片访问 URL |
| `photo_file_path` | `varchar(512)` | N | NULL | 照片存储路径（`/profile/...`） |
| `del_flag` | `char(1)` | Y | `'0'` | `0` 存在 `2` 删除（逻辑删除） |
| `create_by` / `create_time` / `update_by` / `update_time` | 若依惯例 | — | — | 审计 |
| `remark` | `varchar(500)` | N | NULL | 备注 |

**索引**：`PRIMARY KEY (id)`；`KEY idx_pasture_name (pasture_name)`；`KEY idx_pasture_nature (pasture_nature)`；`KEY idx_biz_status (biz_status)`；`KEY idx_create_time (create_time)`；`KEY idx_del_flag (del_flag)`；可选 `KEY idx_id_card (id_card_no)`。

**DDL（MySQL 5.7）**

```sql
CREATE TABLE `biz_pasture` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `pasture_name` varchar(32) NOT NULL COMMENT '牧场名称',
  `pasture_nature` tinyint(4) NOT NULL COMMENT '1个体 2企业',
  `id_card_no` varchar(32) NOT NULL COMMENT '身份证号/主体识别号',
  `province_code` varchar(12) NOT NULL COMMENT '省编码',
  `province_name` varchar(64) NOT NULL COMMENT '省名称',
  `city_code` varchar(12) NOT NULL COMMENT '市编码',
  `city_name` varchar(64) NOT NULL COMMENT '市名称',
  `county_code` varchar(12) NOT NULL COMMENT '县编码',
  `county_name` varchar(64) NOT NULL COMMENT '县名称',
  `detail_address` varchar(100) DEFAULT NULL COMMENT '详细地址',
  `person_in_charge` varchar(32) DEFAULT NULL COMMENT '负责人',
  `contact_phone` varchar(20) NOT NULL COMMENT '联系电话',
  `biz_status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1正常 2停业 3注销',
  `photo_file_url` varchar(512) DEFAULT NULL COMMENT '照片URL',
  `photo_file_path` varchar(512) DEFAULT NULL COMMENT '照片存储路径',
  `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '0存在 2删除',
  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `idx_pasture_name` (`pasture_name`),
  KEY `idx_pasture_nature` (`pasture_nature`),
  KEY `idx_biz_status` (`biz_status`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='牧场管理';
```

### 2.2 枚举常量

| 字段 | 值 | 含义 |
| --- | --- | --- |
| `pasture_nature` | `1` | 个体 |
| | `2` | 企业 |
| `biz_status` | `1` | 正常 |
| | `2` | 停业 |
| | `3` | 注销 |
| `del_flag` | `0` | 正常 |
| | `2` | 已逻辑删除 |

---

## 3. 接口设计

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

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

**Base Path**：`/dataModel/pasture`

| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 3.1 | 分页列表 | GET | `/dataModel/pasture/list` | `dataModel:pasture:list` | Query **3.1.1**；`del_flag=0`；`create_time DESC, id DESC` |
| 3.2 | 详情 | GET | `/dataModel/pasture/{id}` | `dataModel:pasture:query` | 全字段；已删除返回业务失败 |
| 3.3 | 新增 | POST | `/dataModel/pasture` | `dataModel:pasture:add` | Body **3.3.1**；`del_flag=0` |
| 3.4 | 修改 | PUT | `/dataModel/pasture` | `dataModel:pasture:edit` | Body 含 `id`；换照片删旧 |
| 3.5 | 删除 | DELETE | `/dataModel/pasture/{ids}` | `dataModel:pasture:remove` | 逻辑删除 + 删照片文件；支持逗号分隔批量 |

#### 3.1.1 列表 Query

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

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

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `id` | 修改 Y | 主键 |
| `pastureName` | Y | 1～10 字符 |
| `pastureNature` | Y | `1` 或 `2` |
| `idCardNo` | Y | 个体：身份证；企业：主体识别号（建议 18 位） |
| `provinceCode` / `provinceName` | Y | 省级 |
| `cityCode` / `cityName` | Y | 市级 |
| `countyCode` / `countyName` | Y | 县级（须选至县） |
| `detailAddress` | N | ≤50 字 |
| `personInCharge` | N | ≤10 字 |
| `contactPhone` | Y | 大陆手机号 |
| `bizStatus` | Y | `1`～`3`；新增缺省 `1` |
| `photoFileUrl` / `photoFilePath` | N | 成对；可空 |
| `remark` | N | 备注 |

**列表行字段（示例）**：`id`、`pastureName`、`pastureNature`、`idCardNo`（可脱敏）、`provinceName`+`cityName`+`countyName`、`detailAddress`、`personInCharge`、`contactPhone`（可脱敏）、`bizStatus`、`createTime`。

### 3.4 照片与删除

1. 前端 `POST /common/upload` → 写入 `photoFileUrl`、`photoFilePath`（`fileName` 字段）。  
2. 修改替换或逻辑删除时，Service 删除旧 `photo_file_path` 物理文件（路径以 `/profile` 前缀校验）。

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

| 项 | 规则 |
| --- | --- |
| 牧场名称 | 非空，1～10 字符 |
| 牧场性质 | ∈ {1, 2} |
| 证件号 | `pasture_nature=1`：18 位身份证+校验位；`=2`：18 位统一社会信用代码（字母数字，与全局规则一致） |
| 区划 | 省 / 市 / 县 code、name 均非空 |
| 详细地址 / 负责人 | 可空；有值分别 ≤50、≤10 字 |
| 联系方式 | 11 位大陆手机号 |
| 经营状态 | ∈ {1, 2, 3}；新增默认 `1` |
| 照片 | 可空；`jpg`/`jpeg`/`png`；≤10MB；url/path 成对 |

**Mapper 约定**：列表、详情、更新查询均带 `and del_flag = '0'`；删除接口执行 `update biz_pasture set del_flag='2', update_by=?, update_time=now() where id in (...)`。

---

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

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

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

---

## 5. 交付清单

- [ ] `sql/biz_pasture.sql`、菜单与按钮权限 SQL  
- [ ] `BizPasture` Domain / Mapper / Service / Controller  
- [ ] `PastureValidation`（名称、性质、证件联动、区划、手机、照片）  
- [ ] 逻辑删除 + 照片文件清理  
- [ ] 单元测试 / 接口测试（MockMvc）  

---

## 6. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：对齐功能需求；`biz_pasture`；逻辑删除 `del_flag`；区划六级字段；无地图接口 |
