Fixed api issue

This commit is contained in:
m.razaghi
2026-07-12 18:34:10 +03:30
parent 032ae6ebf8
commit abdfe190a7

View File

@@ -10,7 +10,6 @@ use App\Models\BylawNode;
use App\Models\BylawCodificationLink; use App\Models\BylawCodificationLink;
use App\Traits\BaseApiResponse; use App\Traits\BaseApiResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class BylawApiController extends Controller class BylawApiController extends Controller
{ {
@@ -80,8 +79,20 @@ class BylawApiController extends Controller
$perPage = min(max((int) $request->input('per_page', 15), 10), 100); $perPage = min(max((int) $request->input('per_page', 15), 10), 100);
$paginator = $query->paginate($perPage); $paginator = $query->paginate($perPage);
$items = collect($paginator->items())->map(function ($item) { // واکشی دسته‌جمعی و ایمنِ گره‌ها با استفاده از Eloquent
return $this->formatBylaw($item); $docIds = collect($paginator->items())->pluck('id')->map(fn($id) => (int)$id)->toArray();
$nodesByDoc = collect();
if (!empty($docIds)) {
$nodesByDoc = BylawNode::whereIn('document_id', $docIds)
->orderBy('sort_order', 'asc')
->get()
->groupBy(fn($node) => (int)$node->document_id);
}
$items = collect($paginator->items())->map(function ($item) use ($nodesByDoc) {
$itemNodes = $nodesByDoc->get((int)$item->id, collect());
return $this->formatBylaw($item, $itemNodes);
}); });
$responseData = [ $responseData = [
@@ -193,8 +204,19 @@ class BylawApiController extends Controller
$perPage = min(max((int) $request->input('per_page', 15), 10), 100); $perPage = min(max((int) $request->input('per_page', 15), 10), 100);
$paginator = $query->paginate($perPage); $paginator = $query->paginate($perPage);
$items = collect($paginator->items())->map(function ($item) { $docIds = collect($paginator->items())->pluck('id')->map(fn($id) => (int)$id)->toArray();
return $this->formatBylaw($item); $nodesByDoc = collect();
if (!empty($docIds)) {
$nodesByDoc = BylawNode::whereIn('document_id', $docIds)
->orderBy('sort_order', 'asc')
->get()
->groupBy(fn($node) => (int)$node->document_id);
}
$items = collect($paginator->items())->map(function ($item) use ($nodesByDoc) {
$itemNodes = $nodesByDoc->get((int)$item->id, collect());
return $this->formatBylaw($item, $itemNodes);
}); });
$responseData = [ $responseData = [
@@ -233,8 +255,19 @@ class BylawApiController extends Controller
$count = $query->count(); $count = $query->count();
$items = $query->orderBy('approval_date', 'desc')->take(5)->get(); $items = $query->orderBy('approval_date', 'desc')->take(5)->get();
$formattedItems = $items->map(function ($item) { $docIds = $items->pluck('id')->map(fn($id) => (int)$id)->toArray();
return $this->formatBylaw($item); $nodesByDoc = collect();
if (!empty($docIds)) {
$nodesByDoc = BylawNode::whereIn('document_id', $docIds)
->orderBy('sort_order', 'asc')
->get()
->groupBy(fn($node) => (int)$node->document_id);
}
$formattedItems = $items->map(function ($item) use ($nodesByDoc) {
$itemNodes = $nodesByDoc->get((int)$item->id, collect());
return $this->formatBylaw($item, $itemNodes);
}); });
return $this->success([ return $this->success([
@@ -295,9 +328,20 @@ class BylawApiController extends Controller
$itemsToFormat = array_filter([$previousItem, $current, $nextItem]); $itemsToFormat = array_filter([$previousItem, $current, $nextItem]);
$results = array_values(array_map(function($item) { $docIds = collect($itemsToFormat)->pluck('id')->map(fn($id) => (int)$id)->toArray();
return $this->formatBylaw($item); $nodesByDoc = collect();
}, $itemsToFormat));
if (!empty($docIds)) {
$nodesByDoc = BylawNode::whereIn('document_id', $docIds)
->orderBy('sort_order', 'asc')
->get()
->groupBy(fn($node) => (int)$node->document_id);
}
$results = collect($itemsToFormat)->map(function($item) use ($nodesByDoc) {
$itemNodes = $nodesByDoc->get((int)$item->id, collect());
return $this->formatBylaw($item, $itemNodes);
})->values()->toArray();
return $this->success($results, 'Success', 'Pager Window Details'); return $this->success($results, 'Success', 'Pager Window Details');
} }
@@ -311,30 +355,32 @@ class BylawApiController extends Controller
} }
/** /**
* اجرای مستقیم SQL برای دور زدن باگ‌های فیلتر و مدل در لاراول * متد قدرتمند برای استخراج ایمن متون
*/ */
private function formatBylaw($item) private function formatBylaw($item, $itemNodes = null)
{ {
$isLocked = $this->isLockedForCurrentUser($item); $isLocked = $this->isLockedForCurrentUser($item);
// واکشی خام با دستور استاندارد SQL (کاملاً تضمینی) // واکشی در صورت خالی بودن کالکشن
$rawNodes = DB::select("SELECT node_content FROM bylaw_nodes WHERE document_id = ? ORDER BY sort_order ASC", [$item->id]); if ($itemNodes === null) {
$itemNodes = BylawNode::where('document_id', $item->id)->orderBy('sort_order', 'asc')->get();
$extractedTexts = [];
foreach ($rawNodes as $node) {
// حذف فضاهای خالی اضافی بدون حذف محتوای اصلی
$text = trim($node->node_content);
if ($text !== '' && $text !== null) {
$extractedTexts[] = $text;
}
} }
// چسباندن تمام تکه متن‌ها به یکدیگر // استخراج محتوا و تبدیل امنِ Encoding (ضد باگِ JSON Encode لاراول)
$finalNodeContent = implode("\n\n", $extractedTexts); $nodeContentAsDescription = $itemNodes->pluck('node_content')
->map(function ($text) {
// اطمینان از حذف فاصله‌ها و اعمال انکودینگ استاندارد برای جلوگیری از باگ‌های نامرئی
$safeText = trim((string)$text);
return mb_convert_encoding($safeText, 'UTF-8', 'UTF-8');
})
->filter(function ($text) {
return $text !== '';
})
->implode("\n\n");
// بک‌آپ نهایی (اگر به طرز عجیبی واقعاً دیتابیس برای این آیدی هیچ پاسخی نداد) // اگر همچنان خالی ماند (فقط در صورتی که دیتابیس واقعاً رکورد نداشته باشد)
if (empty($finalNodeContent)) { if (empty($nodeContentAsDescription)) {
$finalNodeContent = $item->description; $nodeContentAsDescription = mb_convert_encoding(trim((string)$item->description), 'UTF-8', 'UTF-8');
} }
return [ return [
@@ -356,8 +402,11 @@ class BylawApiController extends Controller
'global_status' => $item->global_status, 'global_status' => $item->global_status,
'pdf_file_url' => $isLocked ? null : ($item->pdf_file_path ? asset('storage/' . $item->pdf_file_path) : null), 'pdf_file_url' => $isLocked ? null : ($item->pdf_file_path ? asset('storage/' . $item->pdf_file_path) : null),
// نتیجه استخراج مستقیم SQL در این متغیر قرار گرفته است: // نتیجه استخراج ۱۰۰٪ در اینجا می‌نشیند
'description' => $isLocked ? null : $finalNodeContent, 'description' => $isLocked ? null : $nodeContentAsDescription,
// 🚨 پارامتر عیب‌یابی: این عدد نشان می‌دهد چند گره متصل به این فایل در دیتابیس پیدا شد
'debug_node_count' => $itemNodes->count(),
'is_locked' => $isLocked, 'is_locked' => $isLocked,
]; ];