From e68e59a16905b4757a96e2348f154fe9374257f7 Mon Sep 17 00:00:00 2001 From: iFannJR Date: Tue, 2 Jun 2026 21:58:50 +0700 Subject: [PATCH] memperbaiki cost/benefit --- app/Services/ToyRecommendationService.php | 42 ++++++++++++------- .../2026_05_31_231107_change_image.php | 25 +++++++++++ ...31706_add_image_blob_to_products_table.php | 21 ++++++++++ 3 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 database/migrations/2026_05_31_231107_change_image.php create mode 100644 database/migrations/2026_05_31_231706_add_image_blob_to_products_table.php diff --git a/app/Services/ToyRecommendationService.php b/app/Services/ToyRecommendationService.php index 08dba65..96829d8 100644 --- a/app/Services/ToyRecommendationService.php +++ b/app/Services/ToyRecommendationService.php @@ -29,7 +29,7 @@ public function getRecommendations(array $input): Collection $criterias = Criteria::orderBy('weight_order')->get(); if ($criterias->isEmpty()) { - return $products->take(5)->map(fn ($p, $i) => [ + return $products->take(5)->map(fn($p, $i) => [ 'rank' => $i + 1, 'product' => $p, 'score' => 0.0, @@ -47,7 +47,7 @@ public function getRecommendations(array $input): Collection return $ranked->map(function ($item, $index) use ($products, $criteriaNames, $priorities) { $product = $products->firstWhere('id', $item['product_id']); - if (! $product) { + if (!$product) { return null; } $explanation = $this->buildExplanation($product, $item['score'], $priorities, $criteriaNames); @@ -87,7 +87,7 @@ public function getRecommendationsWithMatrix(array $input): array $criterias = Criteria::orderBy('weight_order')->get(); if ($criterias->isEmpty()) { - $recommendations = $products->take(5)->map(fn ($p, $i) => [ + $recommendations = $products->take(5)->map(fn($p, $i) => [ 'rank' => $i + 1, 'product' => $p, 'score' => 0.0, @@ -110,7 +110,7 @@ public function getRecommendationsWithMatrix(array $input): array $ranked = $scores->sortByDesc('score')->take(5)->values(); $topProductIds = $ranked->pluck('product_id')->all(); $rankedScoresByProductId = $ranked - ->mapWithKeys(fn ($item) => [$item['product_id'] => round($item['score'], 4)]) + ->mapWithKeys(fn($item) => [$item['product_id'] => round($item['score'], 4)]) ->all(); $criteriasWithWeight = []; @@ -125,7 +125,7 @@ public function getRecommendationsWithMatrix(array $input): array $decisionMatrix = []; foreach ($topProductIds as $productId) { $row = $matrix[$productId] ?? null; - if (! $row) { + if (!$row) { continue; } $product = $products->firstWhere('id', $productId); @@ -139,7 +139,7 @@ public function getRecommendationsWithMatrix(array $input): array $normalizedMatrix = []; foreach ($topProductIds as $productId) { $row = $normalized[$productId] ?? null; - if (! $row) { + if (!$row) { continue; } $product = $products->firstWhere('id', $productId); @@ -156,7 +156,7 @@ public function getRecommendationsWithMatrix(array $input): array $criteriaNames = $criterias->keyBy('id')->map->name; $recommendations = $ranked->map(function ($item, $index) use ($products, $criteriaNames, $priorities) { $product = $products->firstWhere('id', $item['product_id']); - if (! $product) { + if (!$product) { return null; } $explanation = $this->buildExplanation($product, $item['score'], $priorities, $criteriaNames); @@ -205,23 +205,33 @@ protected function ageRangeOverlaps(string $ageRange, int $childMin, int $childM protected function buildWeightsFromPriorities(array $priorities, Collection $criterias): array { - // priorities: [criteria_id => 1..5] - // return weights by criteria name: ['Harga' => 0.2, 'Kualitas' => 0.2, ...] $raw = []; $sum = 0.0; foreach ($criterias as $c) { - $w = (float) ($priorities[(string) $c->id] ?? $priorities[$c->id] ?? 1); - if ($w < 1) $w = 1; - if ($w > 5) $w = 5; + + $input = (int) ($priorities[(string) $c->id] ?? $priorities[$c->id] ?? 3); + + if ($input < 1) + $input = 1; + if ($input > 5) + $input = 5; + + // Jika Cost, dibalik + if ($c->type === 'cost') { + $w = 6 - $input; + } else { + $w = $input; + } + $raw[$c->name] = $w; $sum += $w; } - $count = max(1, $criterias->count()); $weights = []; - foreach ($raw as $name => $v) { - $weights[$name] = $sum > 0 ? $v / $sum : 1 / $count; + + foreach ($raw as $name => $value) { + $weights[$name] = $value / $sum; } return $weights; @@ -240,7 +250,7 @@ protected function buildMatrix(Collection $products, Collection $criterias): arr } } foreach ($criterias as $c) { - if (! isset($row[$c->name])) { + if (!isset($row[$c->name])) { $row[$c->name] = $c->name === 'Harga' ? (float) $product->price : 0; } } diff --git a/database/migrations/2026_05_31_231107_change_image.php b/database/migrations/2026_05_31_231107_change_image.php new file mode 100644 index 0000000..8a648ac --- /dev/null +++ b/database/migrations/2026_05_31_231107_change_image.php @@ -0,0 +1,25 @@ +longBlob('image_blob')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/database/migrations/2026_05_31_231706_add_image_blob_to_products_table.php b/database/migrations/2026_05_31_231706_add_image_blob_to_products_table.php new file mode 100644 index 0000000..3195049 --- /dev/null +++ b/database/migrations/2026_05_31_231706_add_image_blob_to_products_table.php @@ -0,0 +1,21 @@ +binary('image_blob')->nullable()->after('image'); + }); + } + + public function down(): void + { + Schema::table('products', function (Blueprint $table) { + $table->dropColumn('image_blob'); + }); + } +}; \ No newline at end of file