doge 11 ore în urmă
părinte
comite
d9e69a480c

+ 3 - 1
app/Http/Controllers/admin/Issue.php

@@ -150,6 +150,7 @@ class Issue extends Controller
     {
         $id = request()->input('id');
         $winning_numbers = request()->input('winning_numbers');
+        $keno = null;
 
         if (!$id) {
             return $this->error(HttpStatus::CUSTOM_ERROR, '参数错误');
@@ -166,6 +167,7 @@ class Issue extends Controller
             }
 
             $winning_numbers = $playNowInfo['winning_numbers'];
+            $keno = $playNowInfo['source_numbers'] ?? null;
         }
         $winningNumberList = array_map('trim', explode(',', $winning_numbers));
         if (count($winningNumberList) !== 3) {
@@ -187,7 +189,7 @@ class Issue extends Controller
         }
         $winning_numbers = implode(',', $winArr);
         $combo = IssueService::getCombo($winArr);
-        $ret = IssueService::lotteryDraw($id, $winning_numbers, $combo, "");
+        $ret = IssueService::lotteryDraw($id, $winning_numbers, $combo, "", $keno);
         if ($ret['code'] == BaseService::NOT) {
             return $this->error($ret['code'], $ret['error'] ?? $ret['msg']);
         }

+ 61 - 10
app/Http/Controllers/api/Issue.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\api;
 
 use App\Models\Cao;
 use App\Models\CaoHistory;
+use App\Models\Issue as IssueModel;
 use App\Models\Prediction;
 use App\Services\IssueService;
 use Illuminate\Validation\ValidationException;
@@ -24,24 +25,74 @@ class Issue extends BaseController
      * @apiSuccess {Object[]} data
      *
      */
-    function yuanTou()
+    function yuanTou(): JsonResponse
     {
-//        $data = file_get_contents("https://pc28ya.com/index.php?action=getMyOpensJson");
+        $page = max(1, (int)request()->input('page', 1));
+        $limit = min(max(1, (int)request()->input('limit', 20)), 100);
 
-        $page = request()->input('page', 1);
-        $data = file_get_contents("https://pc28ya.com/index.php?Action=MyOpens1&page={$page}");
+        $issues = IssueModel::where('status', IssueModel::STATUS_DRAW)
+            ->whereNotNull('keno')
+            ->where('keno', '!=', '')
+            ->orderByDesc('issue_no')
+            ->forPage($page, $limit)
+            ->get();
+
+        $data = [];
+        foreach ($issues as $issue) {
+            $keno = $this->formatYuanTouKeno($issue->keno);
+            if (empty($keno)) {
+                continue;
+            }
+
+            $winningNumbers = array_map('intval', explode(',', $issue->winning_numbers));
+            $item = [
+                'section' => (string)$issue->issue_no,
+                'openTime' => empty($issue->start_time) ? '' : date('m-d H:i', strtotime($issue->start_time)),
+                'keno' => $keno,
+                'keno_html' => '',
+            ];
 
+            for ($index = 1; $index <= 10; $index++) {
+                $item['openCode' . $index] = (string)($winningNumbers[$index - 1] ?? 0);
+            }
 
-        $data = json_decode($data, true);
-//        $data = array_reverse($data['data']);
-        $data = $data['data'];
-        foreach ($data as &$item) {
-            $item['keno'] = explode(',', $item['keno']);
-            sort($item['keno']);
+            $data[] = $item;
         }
+
         return $this->success($data);
     }
 
+    private function formatYuanTouKeno($keno): array
+    {
+        if (is_string($keno)) {
+            $decoded = json_decode($keno, true);
+            $keno = is_array($decoded) ? $decoded : explode(',', $keno);
+        }
+
+        if (!is_array($keno)) {
+            return [];
+        }
+
+        $numbers = [];
+        foreach ($keno as $number) {
+            $value = filter_var($number, FILTER_VALIDATE_INT, [
+                'options' => [
+                    'min_range' => 1,
+                    'max_range' => 80,
+                ],
+            ]);
+
+            if ($value !== false) {
+                $numbers[] = (int)$value;
+            }
+        }
+
+        $numbers = array_values(array_unique($numbers));
+        sort($numbers, SORT_NUMERIC);
+
+        return array_map('strval', $numbers);
+    }
+
 
     /**
      * @api {get} /issue/history 天机

+ 6 - 1
app/Models/Issue.php

@@ -4,7 +4,7 @@ use App\Services\IssueService;
 class Issue extends BaseModel
 {
     protected $table = 'issues';
-    protected $fillable = ['issue_no', 'start_time', 'end_time', 'winning_numbers', 'status', 'combo', 'extreme', 'image'];
+    protected $fillable = ['issue_no', 'start_time', 'end_time', 'winning_numbers', 'status', 'combo', 'extreme', 'image', 'keno'];
     protected $appends = [
         'award',
         'winning_array',
@@ -27,6 +27,11 @@ class Issue extends BaseModel
         return [];
     }
 
+    function getKenoAttribute($value)
+    {
+        return json_decode($value, true);
+    }
+
     function getAwardAttribute()
     {
         if (!empty($this->winning_numbers)) {

+ 30 - 2
app/Services/IssueService.php

@@ -337,7 +337,7 @@ class IssueService extends BaseService
      * @return {*}
      */
     public
-    static function lotteryDraw($id, $winning_numbers, $combo, $recordImage)
+    static function lotteryDraw($id, $winning_numbers, $combo, $recordImage, $keno = null)
     {
         $info = self::findOne(['id' => $id]);
         if (!$info) {
@@ -356,6 +356,10 @@ class IssueService extends BaseService
             $info->status = self::model()::STATUS_DRAW;
             $info->winning_numbers = $winning_numbers;
             $info->combo = $combo;
+            $kenoJson = self::encodePlayNowKeno($keno);
+            if ($kenoJson) {
+                $info->keno = $kenoJson;
+            }
             $info->saveQuietly();
 
 
@@ -1016,6 +1020,16 @@ class IssueService extends BaseService
         return $normalized;
     }
 
+    private static function encodePlayNowKeno($numbers)
+    {
+        if (!is_array($numbers)) {
+            return null;
+        }
+
+        $numbers = self::normalizePlayNowNumbers($numbers);
+        return $numbers ? json_encode(array_values($numbers)) : null;
+    }
+
     private static function isSamePlayNowIssueNo($issueNo, int $drawNo): bool
     {
         $issueNo = trim((string)$issueNo);
@@ -1176,6 +1190,20 @@ class IssueService extends BaseService
             'next_issue_end_time' => $endTime,
         ]);
 
+        $kenoJson = self::encodePlayNowKeno($drawInfo['source_numbers']);
+        if ($kenoJson) {
+            $drawIssue = self::findOne(['issue_no' => (string)$drawNo]);
+            if ($drawIssue && $drawIssue->status == self::model()::STATUS_DRAW && empty($drawIssue->keno)) {
+                $drawIssue->keno = $kenoJson;
+                $drawIssue->saveQuietly();
+
+                Log::channel('issue')->info('PlayNow源头号码已补写', [
+                    'issue_no' => $drawNo,
+                    'source_numbers' => implode(',', $drawInfo['source_numbers']),
+                ]);
+            }
+        }
+
         $new = true;
 
         $oldList = self::findAll(['status' => self::model()::STATUS_CLOSE]);    // 获取所有封盘的期号
@@ -1194,7 +1222,7 @@ class IssueService extends BaseService
                         'combo' => $combo,
                         'pc28_total' => $pc28['total'],
                     ]);
-                    self::lotteryDraw($v->id, $winning_numbers, $combo, '');
+                    self::lotteryDraw($v->id, $winning_numbers, $combo, '', $drawInfo['source_numbers']);
                     $new = false;
                 } else {
                     Log::channel('issue')->info('开奖期号已处理,跳过重复开奖', [

+ 35 - 0
database/migrations/2026_05_18_000001_add_keno_to_issues.php

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration {
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        if (Schema::hasTable('issues') && !Schema::hasColumn('issues', 'keno')) {
+            Schema::table('issues', function (Blueprint $table) {
+                $table->text('keno')->nullable()->comment('PlayNow官方20个源头号码');
+            });
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        if (Schema::hasTable('issues') && Schema::hasColumn('issues', 'keno')) {
+            Schema::table('issues', function (Blueprint $table) {
+                $table->dropColumn('keno');
+            });
+        }
+    }
+};