101 lines
3.2 KiB
PHP
101 lines
3.2 KiB
PHP
<?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;
|
|
}
|
|
}
|