Files
easygoadmin-wiki/EasyGoAdmin_Gin_Layui/zh/tools/rich-text.md
T
2026-10-20 21:19:44 +08:00

140 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 7.3 富文本处理
:::tip 概述
富文本(如文章内容)中的图片/视频也需要处理。使用 `[IMG_URL]` 占位符机制,支持域名变更场景。
:::
## 处理流程图
```html
┌─────────────────────────────────────────────────────────────────┐
│ 写入流程(add/update) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 前端编辑器插入图片 │
│ │ │
│ ▼ │
│ 上传到临时目录 temp/日期/ │
│ │ │
│ ▼ │
│ 提交 HTML 内容到后端 │
│ │ │
│ ▼ │
│ BaseLogic::processContentFieldsOnSave() │
│ │ │
│ ├─ 解析 <img> 标签的 src │
│ ├─ 解析 <video>/<source>/<embed> 标签的 src │
│ ├─ 解析 <a> 标签的文件 href │
│ │ │
│ ▼ │
│ save_file() 迁移临时文件 → 正式目录 │
│ │ │
│ ▼ │
│ 替换为 [IMG_URL]/相对路径 占位符 │
│ │ │
│ ▼ │
│ 数据库存储含占位符的 HTML │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 读取流程(detail/pageList) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 数据库读取含占位符的 HTML │
│ │ │
│ ▼ │
│ BaseLogic::processContentFieldsOnRead() │
│ │ │
│ ├─ 替换 [IMG_URL] 为实际域名 │
│ │ 如 https://cdn.example.com │
│ │ │
│ ▼ │
│ 返回完整 URL 的 HTML 给前端 │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## 在 Logic 中配置
```php
class ArticleLogic extends BaseLogic
{
/**
* 富文本字段
*
* @var array
*/
protected array $contentFields = ['content'];
}
```
配置后 BaseLogic 自动处理:
- **add/update**:调用 `save_content()` 处理临时文件
- **detail/pageList/allList**:调用 `processContentFieldsOnRead()` 替换占位符
## 为什么使用占位符?
:::tip 域名变更场景
假设初始配置 `FILE.DOMAIN_URL = https://cdn.example.com`,文章内容中图片 URL 为:
`https://cdn.example.com/article/20260920/abc.jpg`
存储时替换为:`[IMG_URL]/article/20260920/abc.jpg`
如果后续域名变更为 `https://cdn2.example.com`,只需修改 `.env` 中的 `FILE.DOMAIN_URL`,已存储的内容无需逐条更新,读取时自动替换为新域名。
:::
## 处理范围
`save_content()` 函数处理以下 HTML 标签:
| 标签 | 属性 | 说明 |
|------|------|------|
| `<img>` | `src` | 图片 |
| `<video>` | `src` | 视频 |
| `<source>` | `src` | 视频源 |
| `<embed>` | `src` | 嵌入内容 |
| `<a>` | `href` | 文件链接(仅处理带扩展名的链接) |
## 代码示例
```php
// app/common.php 中的 save_content 函数
function save_content(string &$content, string $saveDir = 'article'): bool
{
$config = config('file');
$domainUrl = rtrim($config['domain_url'] ?? '', '/');
if (empty($domainUrl) || empty($content)) {
return false;
}
// 收集所有需要处理的 URL
$urlMap = [];
// 1. 匹配 <img> 标签的 src
save_content_match($content, '/<img[^>]+src=["\']?([^"\'>\s]+)/i', $domainUrl, $saveDir, $urlMap);
// 2. 匹配 <video>/<source>/<embed> 标签的 src
save_content_match($content, '/<(?:video|source|embed)[^>]+src=["\']?([^"\'>\s]+)/i', $domainUrl, $saveDir, $urlMap);
// 3. 匹配 <a> 标签的 href(指向文件的情况)
save_content_match($content, '/<a[^>]+href=["\']?([^"\'>\s]+\.\w{2,5})["\']?/i', $domainUrl, $saveDir, $urlMap);
// 批量替换
if (!empty($urlMap)) {
$content = str_replace(array_keys($urlMap), array_values($urlMap), $content);
}
return true;
}
```
## 注意事项
:::warning 富文本安全
- 富文本内容可能包含 XSS 攻击代码,建议在前端使用编辑器的安全模式
- `save_content` 只处理本站域名下的 URL,外部 URL 不做处理
- 图片标签的 `src` 必须是完整 URL(包含域名),否则无法识别
:::