feat: 新增 Docker 部署支持、Swoole/Octane 集成及相关优化
- 添加 Dockerfile 与多套 docker-compose 配置(开发/生产环境) - 集成 Laravel Octane (Swoole) 提升性能 - 新增健康检查、监控脚本及部署文档 - 新增 Docker 镜像离线导入包(MySQL/Redis/Meilisearch) - 优化文档转换、预览服务及队列任务 - 添加 CreateAdminUser 命令与路由健康检查接口 - 新增 Swoole 队列兼容性测试套件 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
55
app/Console/Commands/CreateAdminUser.php
Normal file
55
app/Console/Commands/CreateAdminUser.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreateAdminUser extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'admin:create {email} {password} {--name=系统管理员}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '创建管理员用户';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$email = $this->argument('email');
|
||||
$password = $this->argument('password');
|
||||
$name = $this->option('name');
|
||||
|
||||
// 检查用户是否已存在
|
||||
if (User::where('email', $email)->exists()) {
|
||||
$this->error("用户 {$email} 已存在!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 创建管理员用户
|
||||
$admin = User::create([
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'password' => Hash::make($password),
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
|
||||
$this->info("管理员用户创建成功!");
|
||||
$this->info("姓名: {$admin->name}");
|
||||
$this->info("邮箱: {$admin->email}");
|
||||
$this->info("密码: {$password}");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ class ConvertDocumentToMarkdown implements ShouldQueue
|
||||
$markdown = $result['markdown'];
|
||||
$mediaDir = $result['mediaDir'] ?? null;
|
||||
$tempDir = $result['tempDir'];
|
||||
$tempDirName = $result['tempDirName'];
|
||||
|
||||
try {
|
||||
// 保存 Markdown 文件和媒体文件
|
||||
@@ -88,8 +89,8 @@ class ConvertDocumentToMarkdown implements ShouldQueue
|
||||
$conversionService->updateDocumentMarkdown($this->document, $markdownPath);
|
||||
} finally {
|
||||
// 清理临时目录
|
||||
if (isset($tempDir) && file_exists($tempDir)) {
|
||||
$this->deleteDirectory($tempDir);
|
||||
if (isset($tempDirName) && \Storage::disk('local')->exists($tempDirName)) {
|
||||
\Storage::disk('local')->deleteDirectory($tempDirName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,9 +85,16 @@ class DocumentConversionService
|
||||
throw new \Exception("文档文件不存在: {$documentPath}");
|
||||
}
|
||||
|
||||
// 创建临时工作目录
|
||||
$tempDir = sys_get_temp_dir() . '/pandoc_' . uniqid();
|
||||
mkdir($tempDir, 0755, true);
|
||||
// 使用 Laravel 存储系统创建临时工作目录
|
||||
$tempDirName = 'temp/pandoc_' . uniqid();
|
||||
|
||||
// 确保临时目录存在
|
||||
if (!Storage::disk('local')->exists('temp')) {
|
||||
Storage::disk('local')->makeDirectory('temp');
|
||||
}
|
||||
|
||||
Storage::disk('local')->makeDirectory($tempDirName);
|
||||
$tempDir = Storage::disk('local')->path($tempDirName);
|
||||
|
||||
$tempOutputPath = $tempDir . '/output.md';
|
||||
|
||||
@@ -128,10 +135,11 @@ class DocumentConversionService
|
||||
'markdown' => $markdown,
|
||||
'mediaDir' => $hasMedia ? $mediaDir : null,
|
||||
'tempDir' => $tempDir,
|
||||
'tempDirName' => $tempDirName, // 添加相对路径名
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
// 清理临时目录
|
||||
$this->deleteDirectory($tempDir);
|
||||
Storage::disk('local')->deleteDirectory($tempDirName);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,15 +92,22 @@ class DocumentPreviewService
|
||||
// 创建 HTML Writer
|
||||
$htmlWriter = IOFactory::createWriter($phpWord, 'HTML');
|
||||
|
||||
// 将内容写入临时文件
|
||||
$tempHtmlFile = tempnam(sys_get_temp_dir(), 'doc_preview_') . '.html';
|
||||
$htmlWriter->save($tempHtmlFile);
|
||||
// 使用 Laravel 存储系统创建临时文件
|
||||
$tempFileName = 'temp/doc_preview_' . uniqid() . '.html';
|
||||
|
||||
// 确保临时目录存在
|
||||
if (!Storage::disk('local')->exists('temp')) {
|
||||
Storage::disk('local')->makeDirectory('temp');
|
||||
}
|
||||
|
||||
$tempHtmlPath = Storage::disk('local')->path($tempFileName);
|
||||
$htmlWriter->save($tempHtmlPath);
|
||||
|
||||
// 读取 HTML 内容
|
||||
$htmlContent = file_get_contents($tempHtmlFile);
|
||||
$htmlContent = Storage::disk('local')->get($tempFileName);
|
||||
|
||||
// 删除临时文件
|
||||
unlink($tempHtmlFile);
|
||||
Storage::disk('local')->delete($tempFileName);
|
||||
|
||||
// 将图片嵌入为 base64
|
||||
$htmlContent = $this->embedImagesInHtml($htmlContent, $images);
|
||||
|
||||
Reference in New Issue
Block a user