# 完善组件渲染
## 1。目标
完善页面渲染服务,添加多列布局、地图、联系表单等组件的渲染功能。
## 2。修改文件清单
| 文件 | 操作 | 说明 |
|------|------|------|
| `app/Services/PageRenderService.php` | 修改 | 添加多列布局、地图、联系表单渲染方法 |
---
## 3。修改详情
### 3.1 添加多列布局组件渲染
**文件路径**:`app/Services/PageRenderService.php`
**修改位置**:在 `renderImage` 方法之后
**新增代码**:
```php
/**
* 渲染多列布局组件
*/
protected function renderMultiCol(array $content, array $settings): string
{
$columns = $content['columns'] ?? [];
$columnCount = count($columns);
if ($columnCount === 0) {
return '';
}
$html = '<div class="multi-col" style="padding: 60px 0;">';
$html .= '<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 0 20px;">';
$html .= '<div class="row" style="display: flex; flex-wrap: wrap; gap: 30px;">';
foreach ($columns as $column) {
$html .= '<div class="col" style="flex: 1; min-width: 250px;">';
if (!empty($column['image_url'])) {
$html .= '<img src="' . e($column['image_url']) . '" alt="' . e($column['title']) . '" style="width: 100%; border-radius: 8px; margin-bottom: 20px;">';
}
if (!empty($column['title'])) {
$html .= '<h3 style="font-size: 20px; margin-bottom: 15px;">' . e($column['title']) . '</h3>';
}
if (!empty($column['content'])) {
$html .= '<p style="color: #666; line-height: 1.6;">' . nl2br(e($column['content'])) . '</p>';
}
$html .= '</div>';
}
$html .= '</div></div></div>';
return $html;
}
```
**修改原因**:实现多列布局组件的渲染,支持不同数量的列(2列、3列、4列),每列包含图片、标题和内容。
### 3.2 添加地图组件渲染
**文件路径**:`app/Services/PageRenderService.php`
**修改位置**:在 `renderMultiCol` 方法之后
**新增代码**:
```php
/**
* 渲染地图组件
*/
protected function renderMap(array $content, array $settings): string
{
$address = $content['address'] ?? '';
$title = $content['title'] ?? '地图';
$html = '<div class="map-block" style="padding: 40px 0;">';
$html .= '<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 0 20px;">';
if ($address) {
$html .= '<div style="text-align: center; margin-bottom: 20px;">';
$html .= '<p style="color: #666;">📍 ' . e($address) . '</p>';
$html .= '</div>';
}
$html .= '<div style="background: #f5f5f5; border-radius: 8px; overflow: hidden; min-height: 300px; display: flex; align-items: center; justify-content: center;">';
$html .= '<div style="text-align: center;">';
$html .= '<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#1890ff" stroke-width="1.5">';
$html .= '<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/>';
$html .= '<circle cx="12" cy="9" r="2.5" fill="#1890ff"/>';
$html .= '</svg>';
$html .= '<p style="color: #999; margin-top: 10px;">地图预览区域</p>';
$html .= '<p style="color: #999; font-size: 12px;">' . e($title) . '</p>';
$html .= '</div></div></div></div>';
return $html;
}
```
**修改原因**:实现地图组件的渲染,显示地址信息和地图占位区域(可后续集成百度地图或高德地图 API)。
### 3.3 添加联系表单组件渲染
**文件路径**:`app/Services/PageRenderService.php`
**修改位置**:在 `renderMap` 方法之后
**新增代码**:
```php
/**
* 渲染联系表单组件
*/
protected function renderContactForm(array $content, array $settings): string
{
$title = $content['title'] ?? '联系我们';
$subtitle = $content['subtitle'] ?? '';
$email = $content['email'] ?? '';
$phone = $content['phone'] ?? '';
$address = $content['address'] ?? '';
$html = '<div class="contact-block" style="padding: 60px 0; background: #f8f9fa;">';
$html .= '<div class="container" style="max-width: 800px; margin: 0 auto; padding: 0 20px;">';
$html .= '<h2 style="text-align: center; font-size: 32px; margin-bottom: 15px;">' . e($title) . '</h2>';
if ($subtitle) {
$html .= '<p style="text-align: center; color: #666; margin-bottom: 40px;">' . e($subtitle) . '</p>';
}
$html .= '<div style="display: flex; flex-wrap: wrap; gap: 40px;">';
$html .= '<div style="flex: 1; min-width: 250px;">';
$html .= '<h3 style="margin-bottom: 20px;">联系方式</h3>';
if ($email) {
$html .= '<p style="margin-bottom: 15px; color: #666;">📧 <a href="mailto:' . e($email) . '" style="color: #1890ff; text-decoration: none;">' . e($email) . '</a></p>';
}
if ($phone) {
$html .= '<p style="margin-bottom: 15px; color: #666;">📞 ' . e($phone) . '</p>';
}
if ($address) {
$html .= '<p style="margin-bottom: 15px; color: #666;">📍 ' . e($address) . '</p>';
}
$html .= '</div>';
$html .= '<div style="flex: 2; min-width: 300px;">';
$html .= '<form method="POST" action="/contact/submit" style="display: flex; flex-direction: column; gap: 15px;">';
$html .= '<input type="text" name="name" placeholder="您的姓名" style="padding: 12px; border: 1px solid #ddd; border-radius: 6px;">';
$html .= '<input type="email" name="email" placeholder="您的邮箱" style="padding: 12px; border: 1px solid #ddd; border-radius: 6px;">';
$html .= '<textarea name="message" rows="4" placeholder="留言内容" style="padding: 12px; border: 1px solid #ddd; border-radius: 6px;"></textarea>';
$html .= '<button type="submit" style="background: #1890ff; color: #fff; border: none; padding: 12px; border-radius: 6px; cursor: pointer;">提交留言</button>';
$html .= '</form>';
$html .= '</div></div></div></div>';
return $html;
}
```
**修改原因**:实现联系表单组件的渲染,显示联系信息(邮箱、电话、地址)和留言表单。
---
## 4。验证结果
| 验证项 | 预期结果 | 实际结果 |
|--------|---------|---------|
| 多列布局渲染 | 正常显示多列内容 | ✅ |
| 地图组件渲染 | 显示地图占位区域 | ✅ |
| 联系表单渲染 | 显示表单和联系信息 | ✅ |
---
## 5。提交记录
```bash
git add app/Services/PageRenderService.php
git commit -m "feat(render): 完善组件渲染
- 添加多列布局组件渲染
- 添加地图组件渲染
- 添加联系表单组件渲染"
git push origin main
```
---
# 板块5-5:创建静态文件生成命令
## 1。目标
创建 Artisan 命令,将动态页面一键生成为静态 HTML 文件。
## 2。修改文件清单
| 文件 | 操作 | 说明 |
|------|------|------|
| `app/Console/Commands/GenerateStaticPages.php` | 新建 | 静态文件生成命令 |
---
## 3。修改详情
### 3.1 创建命令
**执行命令**:
```bash
php artisan make:command GenerateStaticPages
```
### 3.2 编写命令代码
**文件路径**:`app/Console/Commands/GenerateStaticPages.php`
**完整代码**:
```php
<?php
namespace App\Console\Commands;
use App\Models\Page;
use App\Services\PageRenderService;
use Illuminate\Console\Command;
class GenerateStaticPages extends Command
{
protected $signature = 'generate:static';
protected $description = '生成静态页面文件';
protected $renderService;
public function __construct(PageRenderService $renderService)
{
parent::__construct();
$this->renderService = $renderService;
}
public function handle()
{
$this->info('开始生成静态页面...');
$pages = Page::where('status', true)->get();
if ($pages->isEmpty()) {
$this->warn('没有已发布的页面');
return 0;
}
$generated = 0;
foreach ($pages as $page) {
$html = $this->renderService->render($page);
if ($page->is_home) {
$filename = 'index.html';
} else {
$filename = $page->slug . '.html';
}
$path = public_path($filename);
file_put_contents($path, $html);
$this->info("已生成: {$filename}");
$generated++;
}
$this->info("生成完成,共生成 {$generated} 个页面");
return 0;
}
}
```
**修改原因**:
- `$signature = 'generate:static'`:定义命令名称为 `generate:static`
- 遍历所有已发布的页面(`status = true`)
- 调用 `PageRenderService` 渲染 HTML
- 首页生成 `index.html`,其他页面生成 `{slug}.html`
- 保存到 `public` 目录
### 3.3 测试命令
**执行命令**:
```bash
php artisan generate:static
```
**预期输出**:
```
开始生成静态页面...
已生成: index.html
已生成: about.html
已生成: contact.html
生成完成,共生成 3 个页面
```
### 3.4 验证文件生成
**执行命令**:
```bash
ls public/*.html
```
**预期输出**:
```
public/about.html public/contact.html public/index.html
```
---
## 4。验证结果
| 验证项 | 预期结果 | 实际结果 |
|--------|---------|---------|
| 命令执行 | 生成 3 个页面 | ✅ |
| `index.html` 生成 | 文件存在 | ✅ |
| `about.html` 生成 | 文件存在 | ✅ |
| `contact.html` 生成 | 文件存在 | ✅ |
---