Files
ai-nav/web10/app/Http/Controllers/CommentController.php

101 lines
3.2 KiB
PHP
Raw Permalink Normal View History

2026-02-05 22:22:10 +08:00
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use App\Models\Comment;
use App\Models\Product;
use App\Models\SensitiveWord;
use App\Models\SiteSetting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class CommentController extends Controller
{
public function captcha()
{
$code = (string) random_int(1000, 9999);
session(['captcha_code' => $code]);
$svg = <<<SVG
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="44">
<rect width="100%" height="100%" fill="#f3f4f6"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"
font-family="Arial, sans-serif" font-size="20" fill="#111827">{$code}</text>
</svg>
SVG;
return response($svg, 200)->header('Content-Type', 'image/svg+xml');
}
public function store(Request $request)
{
if (!SiteSetting::value('comments_enabled', '1')) {
return back()->withErrors(['comments' => '评论功能已关闭。']);
}
$data = $request->validate([
'target_type' => ['required', 'in:product,article'],
'target_id' => ['required', 'integer'],
'nickname' => ['required', 'string', 'max:50'],
'email' => ['nullable', 'email', 'max:255'],
'content' => ['required', 'string', 'max:1000'],
'captcha' => ['required', 'string', 'max:10'],
]);
$captcha = (string) session('captcha_code');
session()->forget('captcha_code');
if ($captcha === '' || $data['captcha'] !== $captcha) {
return back()->withErrors(['captcha' => '验证码错误,请重试。']);
}
$ip = $request->ip() ?? '0.0.0.0';
$rateKey = "comment_rate_{$ip}";
if (Cache::has($rateKey)) {
return back()->withErrors(['comments' => '提交太频繁,请稍后再试。']);
}
Cache::put($rateKey, true, now()->addMinutes(10));
$targetExists = $data['target_type'] === 'product'
? Product::where('id', $data['target_id'])->exists()
: Article::where('id', $data['target_id'])->exists();
if (!$targetExists) {
return back()->withErrors(['comments' => '评论目标不存在。']);
}
$content = $this->filterSensitiveWords($data['content']);
Comment::create([
'target_type' => $data['target_type'],
'target_id' => $data['target_id'],
'nickname' => $data['nickname'],
'email' => $data['email'] ?? null,
'content' => $content,
'status' => 'pending',
'ip' => $ip,
'user_agent' => $request->userAgent(),
]);
return back()->with('success', '评论已提交,审核通过后展示。');
}
public function like(Comment $comment)
{
$comment->increment('like_count');
return back();
}
private function filterSensitiveWords(string $content): string
{
$words = SensitiveWord::pluck('word')->filter()->all();
foreach ($words as $word) {
$content = str_replace($word, str_repeat('*', mb_strlen($word)), $content);
}
return $content;
}
}