# 畜牧监控 — 技术方案

> 依据：同目录 `畜牧监控功能需求.md`（v1.1）。监控点位 **CRUD** + **逻辑删除**；列表**名称模糊**、**所属主体精确**筛选；**不含**实时拉流；主体下拉为养殖主体（正常）+ 交易市场（正常）合并选项。

---

## 1. 技术架构

| 项 | 说明 |
| --- | --- |
| **后端** | RuoYi **v3.9.2**（**springboot2** 分支）：JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| **数据库** | MySQL **5.7.39**，InnoDB，`utf8mb4` |
| **前端** | 若依 Vue2；「查看实时监控」本期仅前端 `Message` 提示，无播放接口 |

**分层**：`Controller` → `Service`（`LivestockMonitorValidation`、主体有效性校验）→ `Mapper`/XML → `domain`。

**代码包（建议）**：`com.ruoyi.web.modules.video`

**业务摘要**

| 场景 | 行为 |
| --- | --- |
| 新增 | 校验字段；校验主体存在且 `del_flag=0`、状态为正常；冗余 `owner_name`；`del_flag=0` |
| 修改 | 全字段可改；可更换主体类型与 ID；更新 `owner_name` |
| 列表/详情 | 仅 `del_flag=0`；排序 `create_time DESC, id DESC`；列表**不返回** `ipAddress` 亦可（前端不展示列即可，接口可带） |
| 列表筛选 | `monitor_name` 模糊；`owner_type` + `owner_id` **精确**（成对） |
| 删除 | `del_flag=2`；**不**校验下游视频平台引用 |
| 唯一性 | **不**校验名称、IP 重复（对齐需求 v1.1） |

---

## 2. 数据库设计

### 2.1 表 `biz_livestock_monitor`（畜牧监控点位）

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `monitor_name` | `varchar(32)` | Y | — | 监控名称（**1～10** 字） |
| `owner_type` | `tinyint(4)` | Y | — | 所属主体类型，见 **§2.3** |
| `owner_id` | `bigint(20)` | Y | — | 主体主键：`biz_pasture.id` 或 `biz_trade_market.id` |
| `owner_name` | `varchar(64)` | Y | — | 主体名称冗余（登记/修改时快照，列表展示用） |
| `install_location` | `varchar(32)` | Y | — | 安装位置（**1～10** 字） |
| `ip_address` | `varchar(20)` | Y | — | IPv4 接入地址（**≤20** 字符） |
| `del_flag` | `char(1)` | Y | `'0'` | `0` 存在 `2` 删除 |
| `create_by` / `create_time` / `update_by` / `update_time` | 若依惯例 | — | — | 审计 |

**索引**：`PRIMARY KEY (id)`；`KEY idx_monitor_name (monitor_name)`；`KEY idx_owner (owner_type, owner_id)`；`KEY idx_create_time (create_time)`；`KEY idx_del_flag (del_flag)`。

> 不设 `(monitor_name)` / `(ip_address)` 唯一索引（需求允许重复）。

### 2.2 DDL（MySQL 5.7）

```sql
CREATE TABLE `biz_livestock_monitor` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `monitor_name` varchar(32) NOT NULL COMMENT '监控名称',
  `owner_type` tinyint(4) NOT NULL COMMENT '1养殖主体 2交易市场',
  `owner_id` bigint(20) NOT NULL COMMENT '主体ID',
  `owner_name` varchar(64) NOT NULL COMMENT '主体名称冗余',
  `install_location` varchar(32) NOT NULL COMMENT '安装位置',
  `ip_address` varchar(20) NOT NULL COMMENT 'IP地址IPv4',
  `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 '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_monitor_name` (`monitor_name`),
  KEY `idx_owner` (`owner_type`, `owner_id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='畜牧监控点位';
```

初始化脚本建议路径：`sql/biz_livestock_monitor.sql`。

### 2.3 枚举

**所属主体类型 `owner_type`**

| 值 | 含义 | 关联表 |
| --- | --- | --- |
| 1 | 养殖主体 | `biz_pasture`（`biz_status=1` 且 `del_flag=0` 可选） |
| 2 | 交易市场 | `biz_trade_market`（`operate_status=1` 且 `del_flag=0` 可选） |

**删除标记 `del_flag`**

| 值 | 含义 |
| --- | --- |
| 0 | 正常 |
| 2 | 已逻辑删除 |

### 2.4 主体主数据校验（Service）

保存/修改时：

| `owner_type` | 校验 SQL 要点 |
| --- | --- |
| 1 | `biz_pasture`：`id=#{ownerId}` AND `del_flag='0'` AND `biz_status=1` |
| 2 | `biz_trade_market`：`id=#{ownerId}` AND `del_flag='0'` AND `operate_status=1` |

失败：`ServiceException`，如「所属主体不存在或已停用」。

`owner_name` 取自主数据 `pasture_name` / `market_name` 写入冗余字段。

---

## 3. 接口设计

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

**权限标识**：`videoSurveillance:livestockMonitor:list|query|add|edit|remove`

**Base Path**：`/videoSurveillance/livestockMonitor`

| # | 说明 | 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 | `/ownerOptions` | `list` |

> 完整路径示例：`GET /videoSurveillance/livestockMonitor/list`。

### 3.1 列表 `GET /list`

**Query**

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `pageNum` / `pageSize` | int | N | 默认 `1` / `20` |
| `monitorName` | string | N | 名称**模糊**：`monitor_name LIKE %value%`（trim 后） |
| `ownerType` | int | N | `1` / `2`；与 `ownerId` **成对**使用 |
| `ownerId` | long | N | **精确**：`owner_type` + `owner_id` 同时匹配 |

**列表行（驼峰）**

| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `monitorName` | 监控名称 |
| `ownerType` | 1 / 2 |
| `ownerTypeName` | 养殖主体 / 交易市场（字典或 Service 填充） |
| `ownerId` | 主体 ID |
| `ownerName` | 冗余展示名 |
| `installLocation` | 安装位置 |
| `createTime` | 创建时间 |

> 列表**可不返回** `ipAddress`（与需求「列表不展示 IP」一致）；详情与编辑回显须含 `ipAddress`。

**排序**：`create_time DESC, id DESC`。

### 3.2 详情 `GET /{id}`

**`data`**：`id`、`monitorName`、`ownerType`、`ownerTypeName`、`ownerId`、`ownerName`、`installLocation`、`ipAddress`、审计字段。

仅 `del_flag=0`；否则失败「记录不存在或已删除」。

### 3.3 新增 `POST /`

### 3.4 修改 `PUT /`

**Body（驼峰）**

| 字段 | 新增 | 修改 | 说明 |
| --- | --- | --- | --- |
| `id` | — | Y | 主键 |
| `monitorName` | Y | Y | 1～10 字，trim |
| `ownerType` | Y | Y | `1` / `2` |
| `ownerId` | Y | Y | 对应主表主键 |
| `installLocation` | Y | Y | 1～10 字 |
| `ipAddress` | Y | Y | IPv4；≤20 字符 |

保存时 Service 解析并写入 `owner_name`（前端**不必**传 `ownerName`，传了也以库内主数据为准覆盖）。

### 3.5 删除 `DELETE /{ids}`

- 路径参数：逗号分隔 id，与若依惯例一致。  
- `UPDATE … SET del_flag='2' WHERE id IN (…) AND del_flag='0'`。  
- 已删 id 忽略或返回 0 条，与项目其他台账一致。

### 3.6 所属主体选项 `GET /ownerOptions`

供列表筛选、新增/编辑下拉（合并数据源，支持模糊搜索）。

**Query**

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `keyword` | string | N | 对 `pasture_name` / `market_name` **模糊**；空则返回前 N 条（建议各表最多 200，合并后按名称排序） |

**响应 `data`：数组项**

| 字段 | 说明 |
| --- | --- |
| `ownerType` | `1` / `2` |
| `ownerTypeName` | 养殖主体 / 交易市场 |
| `ownerId` | 主键 |
| `ownerName` | 展示名称 |

**数据来源（服务端合并）**

1. `biz_pasture`：`del_flag='0'` AND `biz_status=1`；`keyword` 非空时 `pasture_name LIKE`。  
2. `biz_trade_market`：`del_flag='0'` AND `operate_status=1`；`keyword` 非空时 `market_name LIKE`。

> 亦可由前端分别调 `GET /dataModel/pasture/list` 与 `GET /livestock/tradeMarket/list` 自行合并；**推荐**本接口以减少权限与字段差异。

### 3.7 服务端校验（`LivestockMonitorValidation`）

| 项 | 规则 |
| --- | --- |
| 监控名称 | trim 后 1～10 字；非纯空白 |
| 安装位置 | trim 后 1～10 字 |
| IP | IPv4 正则；长度 ≤20；不支持 IPv6/域名 |
| 主体 | `ownerType`∈{1,2}；`ownerId` 非空；**§2.4** 存在且正常 |
| 名称/IP 唯一 | **不校验** |
| 删除 | 记录存在且 `del_flag=0` |

### 3.8 Mapper 约定

- 列表/详情条件均带 `del_flag='0'`。  
- 模糊：`AND monitor_name LIKE CONCAT('%', #{monitorName}, '%')`  
- 主体精确：`AND owner_type = #{ownerType} AND owner_id = #{ownerId}`（两参数均非空时）  
- 逻辑删除：`UPDATE biz_livestock_monitor SET del_flag='2', update_by=?, update_time=? WHERE …`

### 3.9 实时监控（本期）

- **无**后端接口；列表「查看实时监控」由前端 `this.$modal.msgWarning('实时监控功能暂未开放…')` 处理。

---

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

| 类型 | 名称 | 权限标识 | 组件路径 |
| --- | --- | --- | --- |
| 目录 | 视频监控系统 | — | — |
| 菜单 | 畜牧监控 | `videoSurveillance:livestockMonitor:list` | `videoSurveillance/livestockMonitor/index` |
| 按钮 | 查询 | `videoSurveillance:livestockMonitor:query` | — |
| 按钮 | 新增 | `videoSurveillance:livestockMonitor:add` | — |
| 按钮 | 修改 | `videoSurveillance:livestockMonitor:edit` | — |
| 按钮 | 删除 | `videoSurveillance:livestockMonitor:remove` | — |

挂载「视频监控系统」菜单目录下；与 `livestock/*`、`dataModel/*` 路径前缀区分。

---

## 5. 模块关联

| 模块 | 表 / 接口 | 关系 |
| --- | --- | --- |
| 牧场管理 | `biz_pasture` | `owner_type=1`；选项与校验 `biz_status=1` |
| 交易市场管理 | `biz_trade_market` | `owner_type=2`；选项与校验 `operate_status=1` |
| 用户管理 | `sys_user` | 本期无 `sys_user_id`；删除用户时若扩展引用 `biz_livestock_monitor.sys_user_id` 另议（**本期无**） |

---

## 6. 交付清单

- [ ] `sql/biz_livestock_monitor.sql`、菜单权限 SQL  
- [ ] `BizLivestockMonitor`、`LivestockMonitorMapper`/XML、`LivestockMonitorService`、`BizLivestockMonitorController`  
- [ ] `LivestockMonitorValidation`、`ownerOptions` 合并查询  
- [ ] 前端 `videoSurveillance/livestockMonitor/index.vue`、`api/videoSurveillance/livestockMonitor.js`  
- [ ] 单元测试（校验、主体停用、列表 SQL）  
- [ ] MockMvc（list 筛选、CRUD、删除）

---

## 7. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：对齐功能需求 v1.1；`biz_livestock_monitor`；CRUD + `ownerOptions`；无实时流接口 |
