M5: Workerman 常驻服务 + AI 审核/润色插件 + 支付插件(支付宝/微信/沙箱)+ 会员插件(套餐/订阅/付费文章)

This commit is contained in:
ak
2026-08-11 18:29:35 +08:00
parent f77c96d3aa
commit 1d1df43cee
52 changed files with 1914 additions and 20 deletions
@@ -0,0 +1,129 @@
<?php
namespace Plugins\Neatstudio\AiModeration\Filament\Pages;
use App\Models\Post;
use App\Models\Setting;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Schema;
use Plugins\Neatstudio\AiModeration\Jobs\AiPolishContentJob;
class AiSettings extends Page
{
use InteractsWithForms;
protected static \UnitEnum|string|null $navigationGroup = '管理';
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-sparkles';
protected static ?string $navigationLabel = 'AI 设置';
protected string $view = 'plugin.ai-moderation::ai-settings';
public array $data = [];
public ?string $polishPost = null;
public ?string $polishResult = null;
public function mount(): void
{
$this->form->fill([
'llm_base_url' => Setting::get('llm_base_url', env('LLM_BASE_URL')),
'llm_api_key' => Setting::get('llm_api_key', env('LLM_API_KEY')),
'llm_model' => Setting::get('llm_model', env('LLM_MODEL', 'gpt-4o-mini')),
'ai_moderation_enabled' => (int) Setting::get('ai_moderation_enabled', 1) === 1,
'ai_moderation_system_prompt' => Setting::get('ai_moderation_system_prompt', '你是博客评论审核员。判断评论是否包含:广告/垃圾、人身攻击、违法内容、无关灌水。只回复 JSON{"verdict":"approved|rejected|spam","reason":"简短理由"}'),
]);
}
public function form(Schema $schema): Schema
{
return $schema
->components([
\Filament\Schemas\Components\Section::make('LLM 配置')
->description('OpenAI 兼容接口:OpenAI / DeepSeek / 通义 / 自建代理')
->schema([
TextInput::make('llm_base_url')->label('Base URL')->placeholder('https://api.openai.com/v1')->required(),
TextInput::make('llm_api_key')->label('API Key')->password()->required(),
TextInput::make('llm_model')->label('模型')->default('gpt-4o-mini')->required(),
]),
\Filament\Schemas\Components\Section::make('评论审核')
->schema([
Toggle::make('ai_moderation_enabled')->label('新评论启用 AI 自动审核'),
Textarea::make('ai_moderation_system_prompt')->label('审核提示词')->rows(4)->columnSpanFull(),
]),
])
->statePath('data');
}
public function save(): void
{
$data = $this->form->getState();
foreach ($data as $key => $value) {
Setting::set($key, is_bool($value) ? (string) (int) $value : (string) $value);
}
Notification::make()->title('AI 设置已保存')->success()->send();
}
public function polish(Post $post): void
{
$this->polishPost = (string) $post->id;
if ($post->meta['ai_polished'] ?? null) {
$this->polishResult = $post->meta['ai_polished'];
return;
}
dispatch(new AiPolishContentJob($post->id))->onQueue('ai');
Notification::make()->title('润色任务已提交(由 Workerman 异步执行)')->info()->send();
}
public function acceptPolish(Post $post): void
{
$polished = $post->meta['ai_polished'] ?? null;
if (! $polished) {
Notification::make()->title('没有可采纳的润色结果')->warning()->send();
return;
}
$post->update([
'content' => $polished,
'content_format' => 'markdown',
'meta' => array_merge($post->meta ?? [], ['ai_polished' => null]),
]);
Notification::make()->title('已采纳润色结果')->success()->send();
$this->polishResult = null;
}
public function getPendingPolishesProperty(): \Illuminate\Support\Collection
{
return Post::query()
->where('meta->ai_polished', '!=', null)
->latest()
->limit(10)
->get(['id', 'title']);
}
protected function getFormActions(): array
{
return [
Action::make('save')
->label('保存')
->submit('save'),
];
}
}