356 lines
13 KiB
PHP
356 lines
13 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use Illuminate\Http\Request;
|
||
use App\Services\TomTool\Flow;
|
||
use Illuminate\Support\Facades\Http;
|
||
use App\Services\TomTool\Telegram\Slave as TeleSlave;
|
||
use Illuminate\Support\Facades\Storage;
|
||
use App\Models\Gems as ModelGems;
|
||
use App\Models\Articles as ModelArticles;
|
||
use Exception;
|
||
|
||
class ArticleSchemaController extends Controller
|
||
{
|
||
/**
|
||
* 【中央弹药库】全局共享数据与状态
|
||
*/
|
||
private array $aData = [];
|
||
private string $sCmd = '';
|
||
private array $aCmdValue = []; // 修正:类型改为 array,配合 a 前缀
|
||
private string $sGroupCode = '';
|
||
private string $sArticleCode = '';
|
||
private array $aArticleOpt = [];
|
||
// private ?object $oModelGems = null;
|
||
private ?object $oArticleLoc = null;
|
||
private array $aSchemaPro = [];
|
||
|
||
/**
|
||
* 【核心指挥部】接收入口
|
||
*/
|
||
public function receive(Request $oRequest)
|
||
{
|
||
$oFlow = Flow::start("resource-schema-receive");
|
||
|
||
// 1. 数据归仓:强制初始化,防止脏数据
|
||
$this->aData = $oRequest->all();
|
||
$this->sCmd = (string) ($this->aData["cmd"] ?? '');
|
||
$this->aCmdValue = (array) ($this->aData["value"] ?? []);
|
||
$this->sGroupCode = (string) ($this->aData["group_code"] ?? '');
|
||
$this->sArticleCode = (string) ($this->aData["article_code"] ?? '');
|
||
$this->aArticleOpt = (array) ($this->aData["article_opt"] ?? []);
|
||
$this->aSchemaPro = (array) ($this->aData["article"] ?? []);
|
||
|
||
$this->oArticleLoc = ModelArticles::firstOrCreate(
|
||
['sCode' => $this->sArticleCode]
|
||
);
|
||
|
||
//// test
|
||
|
||
//// test end
|
||
|
||
$this->oArticleLoc->sAuthorCode = $this->sGroupCode;
|
||
$this->oArticleLoc->aSchemaPro = $this->aSchemaPro;
|
||
$this->oArticleLoc->aOpt = $this->aArticleOpt;
|
||
$this->oArticleLoc->saveOrFail();
|
||
|
||
try {
|
||
// 参数合法性初审
|
||
if (empty($this->sCmd)) {
|
||
throw new Exception("缺少作战指令 (cmd)");
|
||
}
|
||
|
||
// 2. 指令匹配:一身轻松
|
||
$sMsg = match ($this->sCmd) {
|
||
'new', 'renew' => $this->cmdSaveArticle(),
|
||
'opt' => $this->cmdOptArticle(),
|
||
'del' => $this->cmdDeleteArticle(),
|
||
default => throw new Exception("未知指令: {$this->sCmd}"),
|
||
};
|
||
|
||
return response()->json($oFlow->done($sMsg)->toArray());
|
||
|
||
} catch (Exception $e) {
|
||
$sLog = "【战损报告】" . $e->getMessage();
|
||
TeleSlave::warn()->send($sLog);
|
||
return response()->json(['isDone' => false, 'error' => $e->getMessage()], 500);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 【指令级】处理保存或更新任务
|
||
*/
|
||
private function cmdSaveArticle(): string
|
||
{
|
||
$aArticle = $this->aData["article"] ?? [];
|
||
if (empty($aArticle) || !is_array($aArticle)) {
|
||
throw new Exception("弹药不足:article 数据为空");
|
||
}
|
||
|
||
// 番号匹配
|
||
$aResults = match ($this->sGroupCode) {
|
||
'tg_xiuren_a' => $this->groupXiurenHandler($aArticle),
|
||
default => throw new Exception("番号 {$this->sGroupCode} 未在编制内"),
|
||
};
|
||
|
||
return "{$this->sGroupCode} 任务处理完成,有效战果数: " . count($aResults);
|
||
}
|
||
|
||
/**
|
||
* 【番号级】秀人网专项调度
|
||
*/
|
||
private function groupXiurenHandler(array $aArticle): array
|
||
{
|
||
$aStatus = [];
|
||
|
||
foreach ($aArticle as $aRow) {
|
||
$sRowType = $aRow["type"] ?? '';
|
||
$aRowData = $aRow["data"] ?? [];
|
||
|
||
if (empty($aRowData)) continue;
|
||
|
||
// 类型匹配
|
||
$aStatus[] = match ($sRowType) {
|
||
'photo' => $this->typePhotoHandler($aRowData),
|
||
default => "跳过未知类型: {$sRowType}",
|
||
};
|
||
}
|
||
return $aStatus;
|
||
}
|
||
|
||
/**
|
||
* 【类型级】图片处理处置官
|
||
*/
|
||
private function typePhotoHandler(array $aData): array
|
||
{
|
||
$aSaved = [];
|
||
$sMasterUrl = "https://" . config("path.url_master_base");
|
||
|
||
// 先查出来,拿到实例
|
||
$aImages = $this->oArticleLoc->oImages()
|
||
->where('sArticleCode', $this->sArticleCode)
|
||
->get();
|
||
|
||
// 循环删除,这时每一个都会触发 booted 里的 deleting
|
||
foreach ($aImages as $oImage) {
|
||
$oImage->delete();
|
||
}
|
||
|
||
foreach ($aData as $sPhotoName => $sPhotoUrl) {
|
||
$xBinary = $this->utilDownload($sMasterUrl . "/" . $sPhotoUrl);
|
||
|
||
if ($xBinary) {
|
||
$sFileName = basename($sPhotoUrl);
|
||
// 检查存储结果
|
||
if (Storage::disk('upload_images')->put($sFileName, $xBinary)) {
|
||
$aSaved[] = $sFileName;
|
||
|
||
$this->oArticleLoc->oImages()->create([
|
||
'sArticleCode' => $this->sArticleCode,
|
||
'sFileName' => $sFileName
|
||
]);
|
||
|
||
$this->utilNotify($sFileName, "已保存: " . $sPhotoName);
|
||
}
|
||
}
|
||
}
|
||
return $aSaved;
|
||
}
|
||
|
||
/**
|
||
* 【工具级】资源下载硬攻
|
||
*/
|
||
private function utilDownload(string $sUrl)
|
||
{
|
||
try {
|
||
$oRes = Http::withoutVerifying()
|
||
->timeout(15)
|
||
->retry(3, 200)
|
||
->get($sUrl);
|
||
return $oRes->successful() ? $oRes->body() : null;
|
||
} catch (Exception $e) {
|
||
return null; // 下载失败不炸毁主流程
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 【工具级】Telegram 通报勤务
|
||
*/
|
||
private function utilNotify(string $sFileName, string $sText)
|
||
{
|
||
$sUrl = Storage::disk('upload_images')->url($sFileName); // 统一 Disk
|
||
|
||
if (config("app.is_loc")) {
|
||
$sUrl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
|
||
}
|
||
// var_dump($sUrl);
|
||
// exit;
|
||
|
||
TeleSlave::warn()->setPhotoUrl($sUrl)->send($sText);
|
||
}
|
||
|
||
private function cmdOptArticle(): string
|
||
{
|
||
$sMsg = "resource的opt更新为".json_encode($this->oArticleLoc->opt);
|
||
// TeleSlave::log()->send($sMsg);
|
||
return $sMsg;
|
||
}
|
||
|
||
private function cmdDeleteArticle(): string
|
||
{
|
||
$this->oArticleLoc->delete();
|
||
|
||
return "目标 {$this->sArticleCode} 已从阵地蒸发";
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//public function receive_old(Request $oRequest)
|
||
//{
|
||
// $oFlow = Flow::start("resource-schema-receive");
|
||
//
|
||
// //// test
|
||
// // $oModelSlaveSites = ModelSlaveSites::find(1);
|
||
// // $oModelSlaveSites->oImages()->create([
|
||
// // "sPath" => "xxxx",
|
||
// // ]);
|
||
// //// test
|
||
//
|
||
// $aData = $oRequest->all();
|
||
//
|
||
// $oFlow = $oFlow->setDataA($aData)->fail();
|
||
//
|
||
// $sGroupCode = $aData["_raw"]["group_code"] ?? '';
|
||
// $aArticle = $aData["article"] ?? [];
|
||
// $sCmd = $aData["cmd"] ?? '';
|
||
//
|
||
// $sMasterUrl = "https://".config("path.url_master_base");
|
||
//
|
||
// foreach ($aArticle as $aArticleRow) {
|
||
// if ($sGroupCode == "tg_xiuren_a") {
|
||
// $sArticleRowType = $aArticleRow["type"] ?? "";
|
||
// $aArticleRowData = $aArticleRow["data"] ?? [];
|
||
// if ($sArticleRowType == "photo") {
|
||
// foreach ($aArticleRowData as $sPhotoName => $sPhotoUrl) {
|
||
// $sImgUrl = $sMasterUrl."/".$sPhotoUrl;
|
||
// $sFileName = basename($sPhotoUrl);
|
||
//
|
||
// $oResponse = Http::withoutVerifying() // 放弃证书防线,直接硬攻
|
||
// ->timeout(15) // 15秒决胜负
|
||
// ->retry(3, 200) // 三次冲锋,每次间隔200ms
|
||
// ->get($sImgUrl);
|
||
//
|
||
// if ($oResponse->failed()) {
|
||
// $sMsg = "【战损报告】图片请求全军覆没。URL: {$sImgUrl},状态码: " . $oResponse->status();
|
||
// TeleSlave::warn()->enableSlaveQueue(false)->send($sMsg);
|
||
// continue;
|
||
// }
|
||
//
|
||
// $xData = $oResponse->body();
|
||
//
|
||
// $b = Storage::disk('upload')->put($sFileName, $xData);
|
||
//
|
||
// if (!$b) {
|
||
// $sMsg = "文件保存失败";
|
||
// TeleSlave::warn()->enableSlaveQueue(false)->send($sMsg);
|
||
// }
|
||
//
|
||
// $sResourceImgUrl = Storage::disk('upload')->url($sFileName);
|
||
//
|
||
// if (config("app.is_loc") == true) {
|
||
// $sResourceImgUrl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"; //// test
|
||
// }
|
||
//
|
||
// TeleSlave::warn()->enableSlaveQueue(false)->setPhotoUrl($sResourceImgUrl)->send($sPhotoName);
|
||
//
|
||
// } // foreach articleRow
|
||
// } // articleRow type is photo
|
||
// } // code = xiuren
|
||
// } // foreach article
|
||
//
|
||
// // todo 值入库
|
||
//
|
||
//
|
||
// exit;
|
||
//
|
||
// // return response()->json([
|
||
// // 'status' => '战斗准备就绪',
|
||
// // 'received_id' => $intId,
|
||
// // 'all_data' => $arrData
|
||
// // ]);
|
||
//}
|
||
//
|
||
|
||
|
||
// array(9) {
|
||
// ["site_code"]=>
|
||
// string(8) "resource"
|
||
// ["cmd"]=>
|
||
// string(3) "new"
|
||
// ["value"]=>
|
||
// array(0) {
|
||
// }
|
||
// ["group_code"] = "tg_xiuren_a"
|
||
// ["date"]=>
|
||
// string(19) "2026-01-17 19:54:40"
|
||
// ["_raw"]=>
|
||
// array(13) {
|
||
// ["id"]=>
|
||
// int(126)
|
||
// ["code"]=>
|
||
// string(38) "tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX"
|
||
// ["name"]=>
|
||
// NULL
|
||
// ["schema"]=>
|
||
// string(728) "{"type":"cache_tg","data":[{"type":"photo","photo_fullSizeKey":3,"photo":[{"file_size":1382,"width":60,"height":90,"file_path":"\/private\/var\/www\/wwwroot\/dd.loc\/public\/upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-file_4.jpg"},{"file_size":19420,"width":213,"height":320,"file_path":"\/private\/var\/www\/wwwroot\/dd.loc\/public\/upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-file_5.jpg"},{"file_size":87322,"width":533,"height":800,"file_path":"\/private\/var\/www\/wwwroot\/dd.loc\/public\/upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-file_6.jpg"},{"file_size":169979,"width":853,"height":1280,"file_path":"\/private\/var\/www\/wwwroot\/dd.loc\/public\/upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-file_7.jpg"}]}]}"
|
||
// ["schema_pro"]=>
|
||
// string(325) "[{"type":"photo","data":{"full":"upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-full.jpg","thumb_a":"upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_a.jpg","thumb_b":"upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_b.jpg","thumb_c":"upload\/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_c.jpg"}}]"
|
||
// ["group_code"]=>
|
||
// string(11) "tg_xiuren_a"
|
||
// ["cmd"]=>
|
||
// string(115) "{"|resource|resource|20260117195440|":{"site_code":"resource","cmd":"new","value":[],"date":"2026-01-17 19:54:40"}}"
|
||
// ["cmd_log"]=>
|
||
// NULL
|
||
// ["opt"]=>
|
||
// string(23) "{"thumb_use":["b","c"]}"
|
||
// ["enable_sync"]=>
|
||
// int(1)
|
||
// ["status"]=>
|
||
// int(1)
|
||
// ["created_at"]=>
|
||
// string(27) "2026-01-17T11:54:40.000000Z"
|
||
// ["updated_at"]=>
|
||
// string(27) "2026-01-17T12:07:03.000000Z"
|
||
// }
|
||
// ["key"]=>
|
||
// string(34) "|resource|resource|20260117195440|"
|
||
// ["article_code"]=>
|
||
// string(38) "tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX"
|
||
// ["config"]=>
|
||
// NULL
|
||
// ["article"]=>
|
||
// array(1) {
|
||
// [0]=>
|
||
// array(2) {
|
||
// ["type"]=>
|
||
// string(5) "photo"
|
||
// ["data"]=>
|
||
// array(4) {
|
||
// ["full"]=>
|
||
// string(59) "upload/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-full.jpg"
|
||
// ["thumb_a"]=>
|
||
// string(62) "upload/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_a.jpg"
|
||
// ["thumb_b"]=>
|
||
// string(62) "upload/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_b.jpg"
|
||
// ["thumb_c"]=>
|
||
// string(62) "upload/tg_xiuren_a-01KF5WX0N8VE3D773CFWZQBJVX-fn_b-thumb_c.jpg"
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
|