input("sAuthorCode"); $iNum = (int)$oRequest->input("iNum", 1); $this->iStartNum = $iNum; return $this->findValidUrl($sAuthorCode, $iNum, $oFlow); } public function urlbySubKey(Request $oRequest) { $oFlow = Flow::start("urlBySubKey"); $sSubKey = $oRequest->input("sSubKey"); $iNum = (int)$oRequest->input("iNum", 1); $this->iStartNum = $iNum; return $this->findValidUrlBySubKey($sSubKey, $iNum, $oFlow); } private function findValidUrlBySubKey($sSubKey, $iNum, $oFlow) { try { $sAuthors = ArticleKeyAuthorMap::where("key", $sSubKey)->first()?->authors; $aAuthors = json_decode($sAuthors, true); $oQuery = ModelArticles::whereIn("sAuthorCode", $aAuthors)->orderBy("id", "asc"); $iTotal = $oQuery->count(); if ($iTotal === 0) throw new \Exception("subkey:{$sSubKey} 旗下无任何记录"); // 1. 计算当前查库的偏移量,用 % 取模是最稳的,或者用 if 但不要改 iNum 本身 $iOffset = ($iNum - 1) % $iTotal; $iTrueNum = $iOffset + 1; // 真正对应数据库的第几条 $oArticle = $oQuery->skip($iOffset)->first(); echo "
";var_dump($oArticle->aOpt["thumb_use"]); // 是11
            // 2. 拼文件名
            $aThumbUse = $oArticle->aOpt["thumb_use"] ?? ["b"];
            $sThumbUse = $aThumbUse[array_rand($aThumbUse)];
            if ($sThumbUse == "full") {
                $sFileName = $oArticle->sCode . '-1-' . $sThumbUse . '.jpg';
            } else {
                $sFileName = $oArticle->sCode . '-1-' . 'thumb_' . $sThumbUse . '.jpg';
            }

            // 3. 检查文件
            if (!Storage::disk('upload_images')->exists($sFileName)) {
                // 报警
                TeleSlave::warn()->enableSlaveQueue(false)->enableAsync(false)->send("findValidUrlBySubKey:图片文件不存在:{$sFileName}");

                // 💡 这里的出口判定最重要!
                // 如果尝试次数已经超过了最大限制,或者已经把库里所有的记录都扫了一遍还没找到
                if ($iNum >= ($this->iStartNum + $this->iMaxTry) || $iNum >= ($this->iStartNum + $iTotal)) {
                     throw new \Exception("该作者连续查找多张图片均不存在,已停止尝试");
                }

                // 递归:iNum 必须一直往上涨,不能回头!
                return $this->findValidUrlBySubKey($sSubKey, $iNum + 1, $oFlow);
            }

            // 4. 成功
            $aData = [
                "sFileUrl" => Storage::disk('upload_images')->url($sFileName),
                "iTrueNum" => $iTrueNum,
            ];
            
            return response()->json($oFlow->setDataA($aData)->done()->toArray());

        } catch (\Exception $e) {
            $sMsg = $e->getMessage();
            TeleSlave::warn()->enableSlaveQueue(false)->enableAsync(false)->send($sMsg);
            return response()->json($oFlow->fail($sMsg)->toArray());
        }
    }

    private function findValidUrl($sAuthorCode, $iNum, $oFlow)
    {
        try {
            $oQuery = ModelArticles::where("sAuthorCode", $sAuthorCode)->orderBy("id", "asc");
            $iTotal = $oQuery->count();

            if ($iTotal === 0) throw new \Exception("作者 [{$sAuthorCode}] 旗下无任何记录");

            // 1. 计算当前查库的偏移量,用 % 取模是最稳的,或者用 if 但不要改 iNum 本身
            $iOffset = ($iNum - 1) % $iTotal;
            $iTrueNum = $iOffset + 1; // 真正对应数据库的第几条

            $oArticle = $oQuery->skip($iOffset)->first();

            // 2. 拼文件名
            $aThumbUse = $oArticle->aOpt["thumb_use"] ?? ["b"];
            $sThumbUse = $aThumbUse[array_rand($aThumbUse)];
            if ($sThumbUse == "full") {
                $sFileName = $oArticle->sCode . '-1-' . $sThumbUse . '.jpg';
            } else {
                $sFileName = $oArticle->sCode . '-1-' . 'thumb_' . $sThumbUse . '.jpg';
            }

            // 3. 检查文件
            if (!Storage::disk('upload_images')->exists($sFileName)) {
                // 报警
                TeleSlave::warn()->enableSlaveQueue(false)->enableAsync(false)->send("findValidUrl:图片文件不存在:{$sFileName}");

                // 💡 这里的出口判定最重要!
                // 如果尝试次数已经超过了最大限制,或者已经把库里所有的记录都扫了一遍还没找到
                if ($iNum >= ($this->iStartNum + $this->iMaxTry) || $iNum >= ($this->iStartNum + $iTotal)) {
                     throw new \Exception("该作者连续查找多张图片均不存在,已停止尝试");
                }

                // 递归:iNum 必须一直往上涨,不能回头!
                return $this->findValidUrl($sAuthorCode, $iNum + 1, $oFlow);
            }

            // 4. 成功
            $aData = [
                "sFileUrl" => Storage::disk('upload_images')->url($sFileName),
                "iTrueNum" => $iTrueNum,
            ];
            
            return response()->json($oFlow->setDataA($aData)->done()->toArray());

        } catch (\Exception $e) {
            $sMsg = $e->getMessage();
            TeleSlave::warn()->enableSlaveQueue(false)->enableAsync(false)->send($sMsg);
            return response()->json($oFlow->fail($sMsg)->toArray());
        }
    }
}