# 共同富裕项目 — 技术方案

> 依据：同目录 `共同富裕项目功能需求.md`。本模块为共富项目 CRUD + **发布/下架** + **运营图片（1～3 张）**；运营视频、封面选填。

---

## 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` |
| **代码包** | `com.ruoyi.web.modules.commonprosperity`（建议） |

**分层**：`Controller`（校验、权限、`AjaxResult` / `TableDataInfo`）→ `Service`（发布状态机、运营图子表维护、删物理文件）→ `Mapper`/XML → `domain`。

**发布状态（摘要）**

| 操作 | 前置 `publish_status` | 结果 |
| --- | --- | --- |
| 新增 / 修改 / 删除 / 发布 | `0`（未发布） | 发布 → `1`，写 `publish_time`；删除 → 删主表 + 子表 + 物理文件 |
| 下架 | `1`（已发布） | `0`，写 `offline_time`；**不删**附件 |
| 修改 / 删除 / 发布 | `1` | **拒绝** |

**附件**：表内存 URL + 存储路径（`file_path`）；**不入库**文件大小。运营图片用**子表**（1～3 条），封面与运营视频存**主表**。

---

## 2. 数据库设计

### 2.1 主表 `biz_common_prosperity_project`

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `project_name` | `varchar(64)` | Y | — | 项目名称（**1～20** 字） |
| `project_type` | `tinyint(4)` | Y | — | `1` 合作共赢，`2` 农文旅融合，`3` 认养农业 |
| `introduction` | `varchar(200)` | Y | — | 项目简介（**1～50** 字） |
| `project_content` | `varchar(600)` | Y | — | 项目内容（**1～500** 字） |
| `impl_start_date` | `date` | Y | — | 实施开始日期 |
| `impl_end_date` | `date` | Y | — | 实施结束日期（≥ 开始日） |
| `video_file_url` | `varchar(512)` | N | NULL | 运营视频 URL，选填 |
| `video_file_path` | `varchar(512)` | N | NULL | 运营视频存储路径，选填 |
| `cover_file_url` | `varchar(512)` | N | NULL | 封面 URL，选填 |
| `cover_file_path` | `varchar(512)` | N | NULL | 封面存储路径，选填 |
| `publish_status` | `tinyint(4)` | Y | `0` | `0` 未发布，`1` 已发布 |
| `publish_time` | `datetime` | N | NULL | 发布时间 |
| `offline_time` | `datetime` | N | NULL | 下架时间 |
| `create_by` / `create_time` / `update_by` / `update_time` | 若依惯例 | — | — | 审计 |
| `remark` | `varchar(500)` | N | NULL | 备注 |

**索引**：`PRIMARY KEY (id)`；`KEY idx_create_time (create_time)`；`KEY idx_project_type (project_type)`；`KEY idx_publish (publish_status)`；`KEY idx_impl_start (impl_start_date)`。

### 2.2 子表 `biz_common_prosperity_project_op_image`（运营图片）

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `project_id` | `bigint(20)` | Y | — | 关联主表 `id` |
| `file_url` | `varchar(512)` | Y | — | 图片访问 URL |
| `file_path` | `varchar(512)` | Y | — | 图片存储路径 |
| `sort_order` | `tinyint(4)` | Y | `1` | 排序 `1`～`3`（展示顺序） |
| `create_time` | `datetime` | N | NULL | 创建时间 |

**索引**：`PRIMARY KEY (id)`；`KEY idx_project_id (project_id)`。

**约束（Service 层）**：每个 `project_id` 对应 **1～3** 条记录；`sort_order` 在同一项目内不重复。

### 2.3 DDL（MySQL 5.7）

```sql
CREATE TABLE `biz_common_prosperity_project` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `project_name` varchar(64) NOT NULL COMMENT '项目名称',
  `project_type` tinyint(4) NOT NULL COMMENT '1合作共赢 2农文旅融合 3认养农业',
  `introduction` varchar(200) NOT NULL COMMENT '项目简介',
  `project_content` varchar(600) NOT NULL COMMENT '项目内容',
  `impl_start_date` date NOT NULL COMMENT '实施开始日期',
  `impl_end_date` date NOT NULL COMMENT '实施结束日期',
  `video_file_url` varchar(512) DEFAULT NULL COMMENT '运营视频URL',
  `video_file_path` varchar(512) DEFAULT NULL COMMENT '运营视频存储路径',
  `cover_file_url` varchar(512) DEFAULT NULL COMMENT '封面URL',
  `cover_file_path` varchar(512) DEFAULT NULL COMMENT '封面存储路径',
  `publish_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未发布 1已发布',
  `publish_time` datetime DEFAULT NULL COMMENT '发布时间',
  `offline_time` datetime DEFAULT NULL COMMENT '下架时间',
  `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_create_time` (`create_time`),
  KEY `idx_project_type` (`project_type`),
  KEY `idx_publish` (`publish_status`),
  KEY `idx_impl_start` (`impl_start_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='共同富裕项目';

CREATE TABLE `biz_common_prosperity_project_op_image` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `project_id` bigint(20) NOT NULL COMMENT '项目ID',
  `file_url` varchar(512) NOT NULL COMMENT '图片URL',
  `file_path` varchar(512) NOT NULL COMMENT '图片存储路径',
  `sort_order` tinyint(4) NOT NULL DEFAULT '1' COMMENT '排序1-3',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_project_id` (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='共同富裕项目-运营图片';
```

### 2.4 枚举常量

| 字段 | 值 | 含义 |
| --- | --- | --- |
| `project_type` | `1` | 合作共赢 |
| | `2` | 农文旅融合 |
| | `3` | 认养农业 |
| `publish_status` | `0` | 未发布 |
| | `1` | 已发布 |

---

## 3. 接口设计

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

**权限标识（示例）**：`commonProsperity:project:list|query|add|edit|remove|publish|offline`

**Base Path（示例）**：`/commonProsperity/project`

| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 3.1 | 分页列表 | GET | `/commonProsperity/project/list` | `commonProsperity:project:list` | Query **3.1.1**；排序 `create_time DESC, id DESC`；`rows` 含 `opImageCount`（子表 count） |
| 3.2 | 详情 | GET | `/commonProsperity/project/{id}` | `commonProsperity:project:query` | 主表全字段 + `operationImages[]`（按 `sort_order` 升序） |
| 3.3 | 新增 | POST | `/commonProsperity/project` | `commonProsperity:project:add` | Body **3.3.1**；事务写主表 + 子表；`publish_status=0` |
| 3.4 | 修改 | PUT | `/commonProsperity/project` | `commonProsperity:project:edit` | **仅** `publish_status=0`；全量替换子表；删被移除图片及旧视频/封面物理文件 |
| 3.5 | 删除 | DELETE | `/commonProsperity/project/{ids}` | `commonProsperity:project:remove` | **仅** `publish_status=0`；删主表、子表及全部关联物理文件 |
| 3.6 | 发布 | POST | `/commonProsperity/project/publish/{id}` | `commonProsperity:project:publish` | 前置 `0`；校验必填与子表 1～3 张；`publish_status=1`，`publish_time=now()` |
| 3.7 | 下架 | POST | `/commonProsperity/project/offline/{id}` | `commonProsperity:project:offline` | 前置 `1`；`publish_status=0`，`offline_time=now()` |

#### 3.1.1 列表 Query

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `pageNum` / `pageSize` | int | N | 默认 `1` / `20` |
| `projectName` | string | N | 项目名称**模糊**匹配 |
| `projectType` | int | N | `1`～`3` 精确匹配 |
| `publishStatus` | int | N | `0` / `1` 精确匹配 |

> **App / 前台**：调用同一列表接口时固定传 `publishStatus=1`，仅展示已发布项目。

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

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `id` | 修改 Y | 主键 |
| `projectName` | Y | 1～20 字符 |
| `projectType` | Y | `1`～`3` |
| `introduction` | Y | 1～50 字符 |
| `projectContent` | Y | 1～500 字符 |
| `implStartDate` | Y | `yyyy-MM-dd` |
| `implEndDate` | Y | ≥ `implStartDate` |
| `operationImages` | Y | 数组，**1～3** 项；每项见下表 |
| `videoFileUrl` / `videoFilePath` | N | 运营视频；二者同时有或同时无 |
| `coverFileUrl` / `coverFilePath` | N | 封面；二者同时有或同时无 |
| `remark` | N | 备注 |

**`operationImages[]` 元素**

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `fileUrl` | Y | 上传 `/common/upload` 返回的 `url` |
| `filePath` | Y | 上传返回的 `fileName`（存储路径） |
| `sortOrder` | Y | `1`～`3`，同请求内不重复 |

**列表/详情响应（除 Body 字段外）**

| 字段 | 说明 |
| --- | --- |
| `publishStatus` / `publishTime` / `offlineTime` | 发布状态与时间 |
| `opImageCount` | 仅列表：运营图片数量 |
| `operationImages` | 仅详情：图片数组 |
| `createBy` / `createTime` / `updateBy` / `updateTime` | 审计字段 |

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

| 项 | 规则 |
| --- | --- |
| 项目名称 | 非空，1～20 |
| 项目类型 | ∈ {1,2,3} |
| 项目简介 | 非空，1～50 |
| 项目内容 | 非空，1～500 |
| 实施日期 | `implEndDate` ≥ `implStartDate` |
| 运营图片 | 1～3 张；后缀 `jpg,jpeg,png`；单张 ≤ **10 MB** |
| 运营视频 | 可空；有则后缀 `mp4`（可扩展）；≤ **100 MB**（与产品确认） |
| 封面 | 可空；有则 `jpg,jpeg,png`；≤ **10 MB** |
| 状态 | 已发布禁止修改、删除；未发布禁止下架 |

### 3.5 附件与 Service 流程

1. 前端 `POST /common/upload` → 取 `url`、`fileName`（作 `filePath`）。  
2. 新增：插主表 → 批量插子表。  
3. 修改：比对旧子表 path、旧视频/封面 path → 事务内更新主表、**删子表再插** → 提交后删差异物理文件。  
4. 删除 / 下架：下架不删文件；删除主记录时删子表并删全部 `file_path` / `video_file_path` / `cover_file_path`。

---

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

| 类型 | 名称 | 权限标识 |
| --- | --- | --- |
| 目录 | 共同富裕 | — |
| 菜单 | 共同富裕项目 | `commonProsperity:project:list` |
| 按钮 | 查询 | `commonProsperity:project:query` |
| 按钮 | 新增 | `commonProsperity:project:add` |
| 按钮 | 修改 | `commonProsperity:project:edit` |
| 按钮 | 删除 | `commonProsperity:project:remove` |
| 按钮 | 发布 | `commonProsperity:project:publish` |
| 按钮 | 下架 | `commonProsperity:project:offline` |

组件路径建议：`commonProsperity/project/index`；API 文件 `ruoyi-ui/src/api/commonProsperity/project.js`。

---

## 5. 交付清单

- [ ] `biz_common_prosperity_project`、`biz_common_prosperity_project_op_image` DDL 及菜单权限 SQL（`sql/biz_common_prosperity_project.sql`）
- [ ] `BizCommonProsperityProject` Domain（含 `operationImages` 非表字段）、子表 Mapper、Service、Controller
- [ ] 前端：列表筛选、表单多图上传（限 3）、视频/封面、发布/下架与状态矩阵
- [ ] 用例：运营图 1～3 校验、发布/下架、已发布不可改删、改图删旧文件、App 仅 `publishStatus=1`

---

## 6. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿：对齐功能需求；主表 + 运营图片子表；发布/下架与产业政策宣传一致 |
