# 产业政策宣传 — 技术方案

> 依据：同目录 `产业政策宣传功能需求.md`。本文给出本模块库表与 HTTP 接口约定；**不涉及知识库**，状态仅 `publish_status` 一维。

---

## 1. 技术架构

| 项 | 说明 |
| --- | --- |
| **后端** | RuoYi **v3.9.2**（**springboot2** 分支）：JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| **数据库** | MySQL **5.7.39**，InnoDB，`utf8mb4` |
| **前端** | 若依 Vue2（路由、菜单、按钮权限按项目惯例） |
| **文件** | 复用 RuoYi `/common/upload`；表内存 URL、存储路径、政策文件原始名；**不入库**文件大小 |

**分层**：`Controller`（校验、权限、`AjaxResult` / `TableDataInfo`）→ `Service`（发布状态机、删文件）→ `Mapper`/XML → `domain`。

**状态规则（摘要）**

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

---

## 2. 数据库设计

### 2.1 表 `biz_industry_policy_publicity`（产业政策宣传主表）

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `policy_name` | `varchar(64)` | Y | — | 政策名称（需求 **1～20** 字，列宽留余量） |
| `policy_level` | `tinyint(4)` | Y | — | `1` 国家级，`2` 省级，`3` 市级，`4` 县级 |
| `introduction` | `varchar(200)` | N | NULL | 政策简介，选填 |
| `issue_date` | `date` | Y | — | 出台日期 |
| `policy_desc` | `varchar(200)` | Y | — | 政策描述（需求 ≤50 字） |
| `policy_file_url` | `varchar(512)` | N | NULL | 政策文件访问 URL，选填 |
| `policy_file_path` | `varchar(512)` | N | NULL | 政策文件存储路径，选填 |
| `policy_file_name` | `varchar(256)` | 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_level (policy_level)`；`KEY idx_publish (publish_status)`。

**DDL（MySQL 5.7）**

```sql
CREATE TABLE `biz_industry_policy_publicity` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `policy_name` varchar(64) NOT NULL COMMENT '政策名称',
  `policy_level` tinyint(4) NOT NULL COMMENT '1国家级 2省级 3市级 4县级',
  `introduction` varchar(200) DEFAULT NULL COMMENT '政策简介',
  `issue_date` date NOT NULL COMMENT '出台日期',
  `policy_desc` varchar(200) NOT NULL COMMENT '政策描述',
  `policy_file_url` varchar(512) DEFAULT NULL COMMENT '政策文件URL',
  `policy_file_path` varchar(512) DEFAULT NULL COMMENT '政策文件存储路径',
  `policy_file_name` varchar(256) 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_level` (`policy_level`),
  KEY `idx_publish` (`publish_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产业政策宣传';
```

### 2.2 枚举常量

| 字段 | 值 | 含义 |
| --- | --- | --- |
| `policy_level` | `1` | 国家级 |
| | `2` | 省级 |
| | `3` | 市级 |
| | `4` | 县级 |
| `publish_status` | `0` | 未发布 |
| | `1` | 已发布 |

---

## 3. 接口设计

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

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

**Base Path（示例）**：`/industryPolicy/publicity`

| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 3.1 | 分页列表 | GET | `/industryPolicy/publicity/list` | `industryPolicy:publicity:list` | Query 见下表；排序 `create_time DESC, id DESC` |
| 3.2 | 详情 | GET | `/industryPolicy/publicity/{id}` | `industryPolicy:publicity:query` | 返回全字段；文件下载走 `/common/download` 或鉴权 URL |
| 3.3 | 新增 | POST | `/industryPolicy/publicity` | `industryPolicy:publicity:add` | Body 见 **3.3.1**；落库 `publish_status=0` |
| 3.4 | 修改 | PUT | `/industryPolicy/publicity` | `industryPolicy:publicity:edit` | Body 含 `id`；**仅** `publish_status=0`；替换附件成功后删旧物理文件 |
| 3.5 | 删除 | DELETE | `/industryPolicy/publicity/{ids}` | `industryPolicy:publicity:remove` | **仅** `publish_status=0`；逻辑删或物理删按项目惯例；删 `policy_file_path`、`cover_file_path` 对应文件 |
| 3.6 | 发布 | POST | `/industryPolicy/publicity/publish/{id}` | `industryPolicy:publicity:publish` | 前置 `publish_status=0`；校验必填项；`publish_status=1`，`publish_time=now()` |
| 3.7 | 下架 | POST | `/industryPolicy/publicity/offline/{id}` | `industryPolicy:publicity:offline` | 前置 `publish_status=1`；`publish_status=0`，`offline_time=now()`；**不删**附件 |

#### 3.1 列表 Query 参数

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `pageNum` | int | N | 默认 `1` |
| `pageSize` | int | N | 默认 `20` |
| `keyword` | string | N | 政策名称 / 政策简介 **OR** 模糊 |
| `policyLevel` | int | N | 政策层级精确匹配，空则不过滤 |
| `publishStatus` | int | N | `0` / `1`，空则不过滤 |

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

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `id` | 修改必填 | 主键 |
| `policyName` | Y | 1～20 字符 |
| `policyLevel` | Y | `1`～`4` |
| `introduction` | N | ≤50 字 |
| `issueDate` | Y | `yyyy-MM-dd`，不得为未来日期 |
| `policyDesc` | Y | ≤50 字 |
| `policyFileUrl` / `policyFilePath` / `policyFileName` | N | 上传 `/common/upload` 后填入；三者同时有或同时无 |
| `coverFileUrl` / `coverFilePath` | N | 封面；二者同时有或同时无 |
| `remark` | N | 备注 |

**列表/详情响应字段**：与上表对应；另含 `publishStatus`、`publishTime`、`offlineTime`、`createTime` 等。

### 3.8 校验（服务端）

| 项 | 规则 |
| --- | --- |
| 政策名称 | 非空，长度 1～20 |
| 政策层级 | ∈ {1,2,3,4} |
| 政策简介 | 可空；有值则 ≤50 字 |
| 出台日期 | 合法日期；默认不允许 &gt; 当天 |
| 政策描述 | 非空，≤50 字 |
| 政策文件 | 可空；有则后缀 `pdf,md,doc,docx,xls,xlsx,ppt,pptx`，≤30MB |
| 封面 | 可空；有则后缀 `jpg,jpeg,png`，≤10MB |
| 状态 | 已发布禁止修改、删除；未发布禁止下架 |

### 3.9 附件流程

1. 前端调 `POST /common/upload` → 取 `url`、`fileName`（作 path）、`originalFilename`（政策文件作 `policyFileName`）。  
2. 新增/修改提交 URL + path + 原始名。  
3. 修改替换或删除记录时，Service 删除旧 `policy_file_path`、`cover_file_path` 物理文件。

---

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

| 类型 | 名称 | 权限标识 |
| --- | --- | --- |
| 菜单 | 产业政策宣传 | `industryPolicy:publicity:list` |
| 按钮 | 查询 | `industryPolicy:publicity:query` |
| 按钮 | 新增 | `industryPolicy:publicity:add` |
| 按钮 | 修改 | `industryPolicy:publicity:edit` |
| 按钮 | 删除 | `industryPolicy:publicity:remove` |
| 按钮 | 发布 | `industryPolicy:publicity:publish` |
| 按钮 | 下架 | `industryPolicy:publicity:offline` |

组件路径建议：`industryPolicy/publicity/index`（与 RuoYi 代码生成/手工目录一致即可）。

---

## 5. 交付清单

- [ ] `biz_industry_policy_publicity` DDL、菜单与按钮权限 SQL  
- [ ] `IndustryPolicyPublicity` Domain / Mapper / Service / Controller  
- [ ] 前端列表、表单、详情、发布/下架按钮与状态控制  
- [ ] 用例：增删改查、发布、下架、已发布不可改删、附件替换删旧文件、列表筛选  

---

## 6. 修订记录

| 日期 | 说明 |
| --- | --- |
| — | 初稿：对齐功能需求；无知识库字段；政策文件/封面可空；发布无需 `kb_sync_status` |
