no message

This commit is contained in:
hellcat 2025-06-10 17:16:53 +08:00
parent 9d5a60dd63
commit 2bb70f727b
12 changed files with 2656 additions and 343 deletions

View File

@ -7,6 +7,7 @@ namespace App\Http\Controllers\Api\TG;
//use App\Models\Article;
use App\Services\TomTool\Http;
use App\Services\TG\Http as TGHttp;
use App\Models\Hook as ModelHook;
final class HookController
{
@ -23,52 +24,69 @@ final class HookController
$sUpdate = file_get_contents("php://input");
$aUpdate = json_decode($sUpdate, true);
// @file_put_contents('/www/_tg/bot_log.txt', json_encode($aUpdate, JSON_PRETTY_PRINT));
$aData['chatId'] = $aUpdate["message"]["chat"]["id"];
$aData['fromId'] = $aUpdate["message"]["from"]["id"];
$aData['chatId'] = (string) $aUpdate["message"]["chat"]["id"];
$aData['fromId'] = (string) $aUpdate["message"]["from"]["id"];
if (!isset($aUpdate["message"]["text"])) {
throw new \Exception("");
}
$sText = $aUpdate["message"]["text"];
$sText = &$aUpdate["message"]["text"];
@$aArg = explode(" ", $sText);
@$aOption = explode("__", $aArg[0]);
// hook优先
// 非is_hook并且首字符非/
if ((!isset($aUpdate["is_hook"]) || $aUpdate["is_hook"] == false) && substr($sText, 0, 1) !== "/") {
$sHookKey = ModelHook::where("tg_user_id", $aData["fromId"])->first()?->key;
if ($sHookKey) {
if ($sText == "run") {
$sText = $sHookKey;
} else {
$sText = $sHookKey.$sText;
}
$aUpdate["is_hook"] = true;
}
}
@$aArg = explode(" ", $sText) ?? [];
@$aOption = explode("__", $aArg[0]) ?? [];
$sCmd = $this->cleanCmd($aOption[0]);
// 大于3个说明是hook或dove之类
$aCmd = explode("#", $sCmd);
if (count($aCmd) >= 3) {
$sHook = $aCmd[0];
$sClass = $sHook;
$sFunc = "go";
} else {
// if (count($aCmd) >= 3) {
// $sHook = $aCmd[0];
// $sClass = $sHook;
// $sFunc = "go";
// } else {
$sClass = $aCmd[0];
$sFunc = $aCmd[1];
}
// if ($sClass == "book" || $sClass == "Book") {
// if (strpos($sFunc, '/') !== false) {
// echo "字符串中包含斜杠。";
// }
// }
if (strpos($sClass, "dove%") !== false) {
$sClass = "dove";
$sFunc = "go";
}
$sUClass = ucfirst($sClass);
$sUFunc = ucfirst($sFunc);
$sUClass = ucfirst($sClass);
$sUFunc = ucfirst($sFunc);
unset($aOption[0]);
unset($aArg[0]);
$aParams = [];
$aParams['aOption'] = $aOption;
$aParams['aArg'] = $aArg;
$sClassPath = "App\\Services\\TG\\Hook\\Mod\\".$sClass;
$sUClassPath = "App\\Services\\TG\\Hook\\Mod\\".$sUClass;
// 兼容大小写,自己挖的坑
if (method_exists($sClassPath, $sFunc)) {
$oInstans = new $sClassPath();
@ -77,12 +95,13 @@ final class HookController
$oInstans = new $sUClassPath();
$r = $oInstans->$sUFunc($aParams, $aUpdate);
} else if ($sClass == "book" || $sClass == "Book") {
$sFunc = "cd";
$sFunc = "main";
$oInstans = new $sUClassPath();
$r = $oInstans->$sFunc($aParams, $aUpdate);
} else {
throw new \Exception("没有这个方法:".$sClass.'#'.$sFunc);
}
if (isset($r)) {
// 返回可以是数组
if (is_array($r)) {
@ -97,31 +116,6 @@ final class HookController
} else {
throw new \Exception("?!?!?!?!");
}
// if (method_exists($sClassPath, $sFunc)) {
// $oInstans = new $sClassPath();
// $r = $oInstans->$sFunc($aParams, $aUpdate);
//
// // 可以不返回里面直接send
// if (isset($r)) {
//// if (empty($r)) { $r = 'hook的mod返回空'; }
// // 返回可以是数组
// if (is_array($r)) {
// foreach ($r as $row) {
// $oTGHttp->sendToTG($row);
// }
// } else {
// $oTGHttp->sendToTG($r);
// }
//
// Http::response(200, 'ok');
// }
//
// } else {
// throw new \Exception("没有这个方法:".$sClass.'#'.$sFunc);
// }
} catch (\Throwable $e) {
$sMessage = "错误line:".$e->getLine().": " . $e->getMessage();

View File

@ -0,0 +1,69 @@
<?php
namespace App\Http\Controllers;
//use Illuminate\Http\Request;
//use App\Models\ArticleList;
//use App\Services\Time;
//use voku\helper\AntiXSS;
//use App\Models\Tags;
//use App\Services\TomTool\Http;
use App\Models\Book as ModelBook;
use App\Models\BookOption as ModelBookOption;
use App\Services\TG\Http as TGHttp;
class CronController
{
public $oTGHttp;
function __construct()
{
$this->oTGHttp = new TGHttp();
$this->oTGHttp->sApiToken = env('telegram_token');
$this->oTGHttp->sApiChatId = env('telegram_chatid');
}
public function index()
{
$h = date("H");
$i = date("i");
$s = date("s");
//// test
$h = "00";
//// test end
if ($h == "00") {
$iFireWarningLine = ModelBookOption::_hit("fire_warning_line");
$sDateWarningLine = date("Y-m-d H:i:s", strtotime($iFireWarningLine."day"));
$oBook = ModelBook::whereDate("fire", "<=", $sDateWarningLine)->where("fire_close", 0)->get();
if (!$oBook->isEmpty()) {
$oDateNow = new \DateTime();
foreach ($oBook as $oBookRow) {
$oDateRag = new \DateTime($oBookRow->fire);
$iDiffDay = $oDateNow->diff($oDateRag)->days;
if ($oDateNow > $oDateRag) {
$iDiffDay = -$iDiffDay;
}
$sTgStr = "⚠️⚠️⚠️ {{ ".$oBookRow->rag." }} 还有 {{ ".$iDiffDay." }} 天到期";
$this->oTGHttp->sendToTG($sTgStr);
}
}
}
}
}

View File

@ -11,10 +11,30 @@ use App\Services\TomTool\Http;
class SakaiController
{
// public function hook()
// {
function __construct()
{
// $sPath = ModelBookHook::_first_path();
//
// }
// if ($sPath) {
// $this->sPath = $sPath;
// } else {
// $this->sPath = "/";
// }
//
// $this->iPageNo = $this->_getPageNo() ?? 1;
//
// $aTmp = ModelBookOption::all()->toArray();
// foreach ($aTmp as $v) {
// $this->aOption[$v["key"]] = $v["value"];
// }
//
// $this->oRag = $this->_getParentRag();
//// $this->oRag->option = $this->oRag->option ? json_decode($this->oRag->option, true) : [];
}
public function test1()
{
@ -86,6 +106,196 @@ class SakaiController
$s = "/book#o 8";
$s = "/book#seto__8 99991919191";
$s = "/note#now";
$s = "book#up 3";
$s = "book#add 3";
$s = "book#";
$s = "book#add 1231";
$s = "book#no 2";
$s = "book#back";
$s = "book#add jjjjjjjjjjj";
$s = "book#open";
$s = "book#add 1";
$s = "book#no 1";
$s = "book#add 11111111111";
$s = "book#back";
// $s = "book#no 1";
$s = "book#mark__un 5";
$s = "book#set__2 222222";
$s = "book#del 3";
$s = "book#no_to 1 3";
$s = "book#down 1";
$s = "book#check 1";
$s = "book#del_";
$s = "book#to_ 3";
$s = "book#to 3 1";
$s = "book#to_ 3";
// $s = "book#to 4 5";
$s = "book#down";
$s = "book#check 3 1 2 8 99";
// $s = "book#check_clear";
$s = "book#list";
$s = "book#no 2";
$s = "book#add 123123";
$s = "book#back";
$s = "book#open";
$s = "book#mark_un 3 4";
$s = "book#markR";
$s = "book#mark_un 3 4";
$s = "book#checked 3 4";
$s = "book#markR_un";
$s = "book#set__1 123";
$s = "book#mark 1 3";
$s = "book#mark__un 1";
$s = "book#mark";
$s = "book#mark__un";
$s = "book#set";
$s = "book#set 999";
$s = "book#set__text 999111222";
$s = "book#set_no__6__memo 6666";
$s = "book#set_no__5__6 x";
$s = "book#set kkkxx";
$s = "book#del 1 5";
$s = "book#del_show";
$s = "book#del_clear";
$s = "book#open";
$s = "book#up__3__5__2";
$s = "book#to__2__4 6";
$s = "book#to 3";
$s = "book#up";
$s = "book#down";
$s = "book#check 1 3 5";
$s = "book#del_back";
$s = "book#nick vv";
$s = "book#detail";
$s = "book#detail__all 1 2";
$s = "book#del 3";
$s = "book#del_done";
$s = "book#nick xx";
$s = "book#hit__id__nick";
$s = "book#tag_no kkkkss";
$s = "book#tag zz";
$s = "book#tags";
$s = "book#fire__1 2025-01-01 11:11:11";
$s = "book#open";
$s = "book#fire_line";
$s = "book#rank__1 2";
$s = "book#add 222";
$s = "book#open";
// $s = "book#rank war";
// $s = "book#move main";
$s = "book#check_clear";
$s = "book#check 6 7";
$s = "book#move 8";
$s = "book#open";
// $s = "book#del 1";
// $s = "book#no 8";
$s = "book#move 1";
$s = "book#rag__4 bb";
$s = "book#no 1";
$s = "book#back";
$s = "book#move_no__2 1 3";
$s = "book#move_no__2 back";
$s = "book#open";
// $s = "book#rag 66";
// $s = "book#del 5";
// $s = "book#move_no__5 6";
// $s = "book#back";
//// $s = "book#no 2";
//// $s = "book#rag book";
//// $s = "book#move_no__2 1";
//// $s = "book#move_no__back 4";
//// $s = "book#no 1";
//// $s = "book#rag red";
// $s = "book#check 1";
// $s = "book#move main";
// $s = "book#detail 6";
$s = "book#tree";
$s = "book#openRe";
// $s = "book#open";
// $s = "book#exp 4";
// $s = "book#uu 4";
//// $s = "book#option__page_limit 4";
//// $s = "book#option_hit page_limit";
//// $s = "book#option_add__zz bb";
//// $s = "book#limit 7";
// $s = "book#page 3";
// $s = "book#path /";
// $s = "book#pageRe";
// $s = "book#openRe";
// $s = "book#tree";
// $s = "book#p";
// $s = "book#order id 1";
$s = "book#order no 1";
$s = "book#type 22";
$s = "book#page 1";
$s = "book#del_show";
$s = "book#ing 2 3";
$s = "book#page 1";
$s = "book#limit 10";
$s = "book#no 1";
$s = "book#rag 2222";
$s = "book#type todo_main";
$s = "book#open";
// $s = "book#action 1";
// $s = "book#unsort";
$s = "book#keep 1";
$s = "book#action 1";
// $s = "book#openRe";
$s = "book#option";
$s = "book#openRe";
$s = "book#type todo";
$s = "book#parent_hit order";
$s = "book#parent_set order _todo";
$s = "book#srank war";
$s = "book#unsort";
$s = "book#action 3";
$s = "book#open";
$s = "book#open";
$s = "book#rag lll";
$s = "book#action 5";
$s = "book#todo__war zzz";
$s = "book#toKeep uuuuu";
$s = "book#parent_detail";
$s = "book#parent_hit limit";
$s = "book#parent_set limit 22";
$s = "book#fire 2025-11-11 22:22:22";
$s = "book#openRe";
$s = "book#order fire desc";
$s = "book#fire 3#day";
$s = "book#fire";
$s = "book#checkId 90013";
$s = "book#test";
$s = "book#tt";
$s = "book#back";
$s = "book#openRe";
$s = "book#order rank_todo asc";
$s = "book#option";
$s = "book#ragOptionSet__tt 2222";
$s = "book#ragOption";
$s = "book#openRe";
$s = "book#fire_toggle";
$s = "book#open";
// $s = "book#check 1";
// $s = "book#parent_set order_type asc";
// $s = "book#Open";
// $s = "hook#set dove#book#open";
// $s = "open";
$s = "main";
$s = "fire_toggle";
$s = "/hook#set dove%book#";
$s = "/hook#now";
$s = "/hook#un";
$s = "/book#firel";
$s = "/book#main";
$s = "/book#sort rank war";
$s = "/book#option";
// $s = "/book#optionDel zz";
// $s = "/book#optionSet zz mm";
// $s = "/book#optionSet where rank='war'";
$s = "book#main";
$s = "/book#where rank = 'war' or rag like '%o%'";
// movetoId和like列表
$oHttp = new Http();
$oHttp->sMethod = "post";

View File

@ -3,9 +3,128 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
//use BookOption as ModelBookOption;
class Book extends Model
{
protected $table = 'book';
public $timestamps = false;
// public $timestamps = false;
protected static $sFieldNick = [
'text' => 'title',
'memo' => 'title',
'txt' => 'title',
't' => 'title',
];
public static function _mapField($sField)
{
if (isset(self::$sFieldNick[$sField])) {
return self::$sFieldNick[$sField];
} else {
return $sField;
}
}
public static function _no($sPath, $iNo, $iIsDel = 0)
{
$oSelf = self::where("path", $sPath)->where("no", $iNo)->orderBy("no")->first();
return $oSelf;
}
public static function _no_arr($sPath, $aNo, $iIsDel = 0)
{
$oSelf = self::where("path", $sPath)->whereIn("no", $aNo)->orderBy("no")->get();
return $oSelf;
}
public static function _id_arr($sPath, $aId, $iIsDel = 0)
{
$oSelf = self::where("path", $sPath)->whereIn("id", $aId)->orderBy("no")->get();
return $oSelf;
}
public static function _path($sPath, $iPage = 1, $iIsDel = 0)
{
// 获取上级id
if ($sPath == "/") {
$iParentId = "1";
} else {
$tmp = trim($sPath, "/");
$aPath = explode("/", $tmp);
$tmp = count($aPath);
$iParentId = $aPath[$tmp-1];
}
// 获取上级rag
$oParentRag = self::where("id", $iParentId)->first();
// $oParentRag
// 上级属性
$sOrder = $oParentRag->order ?? "no";
$sOrderType = $oParentRag->order_type ?? "asc";
// 上级option
$aRagOption = json_decode($oParentRag->option, 1);
// tomd($aRagOption, 1);
if (empty($oParentRag->limit)) {
$iLimit = BookOption::_hit("page_limit");
} else {
$iLimit = $oParentRag->limit;
}
$oSelf = self::where("path", $sPath)->where("is_del", $iIsDel);
if (isset($aRagOption["where"])) {
$oSelf = $oSelf->whereRaw($aRagOption["where"]);
}
// if ($oParentRag->sort) {
// $aSort = explode("_", $oParentRag->sort);
// $oSelf = $oSelf->where($aSort[0], $aSort[1]);
// }
if ($oParentRag->order == "rank_todo") {
$sTodoOrder = BookOption::_hit("order_rank_todo");
$aOrder = explode(",", $sTodoOrder);
if ($iPage !== "all") {
$oSelf = $oSelf->where("rank", "!=", "done");
$oSelf = $oSelf->where("rank", "!=", "block");
}
$oSelf = $oSelf->orderByRaw("rank IS NULL, FIELD(rank, " . $sTodoOrder . ") ".$sOrderType);
$oSelf = $oSelf->orderByRaw("fire IS NULL, fire ASC");
$sOrder = "no";
$sOrderType = "asc";
}
$oSelf = $oSelf->orderBy($sOrder, $sOrderType);
$oSelf = $oSelf->orderBy("updated_at", "desc");
if ($iPage == "all") {
$oSelf = $oSelf->get();
} else {
$oSelf = $oSelf->paginate($iLimit, ['*'], 'page', $iPage);
}
return $oSelf;
}
public static function _noByChecked($sPath, $sType = "no")
{
$aNo = self::where("path", $sPath)->where("checked", 1)->pluck($sType)->toArray();
return $aNo;
}
}

View File

@ -3,24 +3,47 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class BookHook extends Model
{
protected $table = 'book_hook';
public $timestamps = false;
public static function _first($sType)
// public static function _first($sType)
// {
// $oData = first();
//
// return $oData;
// }
//
// public static function _first_key($sType)
// {
// $sKey = self::where("type", $sType)->first()?->key;
//
// return $sKey;
// }
public static function _first_path()
{
$oData = self::where("type", $sType)->first();
$oSelf = self::first()?->path;
return $oData;
return $oSelf;
}
public static function _first_key($sType)
public static function _cd($sPath)
{
$sKey = self::where("type", $sType)->first()?->key;
return $sKey;
DB::table('book_hook')->truncate();
$oBookHook = new self();
$oBookHook->path = $sPath;
$r = $oBookHook->save();
return $r;
}
}

View File

@ -8,4 +8,11 @@ class BookOption extends Model
{
protected $table = 'book_option';
public $timestamps = false;
public static function _hit($sKey)
{
$sValue = self::where("key", $sKey)->first()?->value;
return $sValue;
}
}

33
app/Models/BookPage.php Executable file
View File

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BookPage extends Model
{
protected $table = 'book_page';
public $timestamps = false;
protected $fillable = [
'path', // 添加 path 字段
'content', // 其他字段
'exp_no'
// 其他你希望允许批量赋值的字段
];
// protected static $sFieldNick = [
// 'text' => 'title',
// 'memo' => 'title',
// 'txt' => 'title',
// 't' => 'title',
// ];
public static function byPath($sPath)
{
$oBookPage = self::where("path", $sPath)->first();
return $oBookPage;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,31 +4,34 @@ namespace App\Services\TG\Hook\Mod;
//use App\Models\Hook as ModelHook;
use App\Models\DoveSite as ModelDoveSite;
use App\Services\TomTool\Http;
class Dove extends Base {
public function go($aParam, $aData)
{
$oDoveSiteCheckedList = ModelDoveSite::where("dove_checked", 1)->get();
list(, $sSubCmd) = explode("#", $aData['message']['text'], 2);
$aData['message']['text'] = "/".$sSubCmd;
list(, $sSubCmd) = explode("%", $aData['message']['text'], 2);
$aData['message']['text'] = $sSubCmd;
$aData['dove_token'] = env('dove_token');
$oHttp = new Http();
$oHttp->sMethod = "post";
$oHttp->bIsJson = true;
foreach ($oDoveSiteCheckedList as $row) {
$sApiUrl = "https://".$row->www.$row->api_path;
$this->oHttp->sMethod = "post";
$this->oHttp->bIsJson = true;
$this->oHttp->sToUrl = $sApiUrl;
$this->oHttp->aData = $aData;
$r = $this->oHttp->send();
return $r;
$oHttp->sToUrl = $sApiUrl;
$oHttp->aData = $aData;
$r[] = $oHttp->send();
}
return $r;
}
public function set($aParam)

View File

@ -3,7 +3,8 @@
namespace App\Services\TG\Hook\Mod;
use App\Models\Hook as ModelHook;
use App\Models\SiteList as ModelSiteList;
//use App\Models\SiteList as ModelSiteList;
//use App\Services\TomTool\Http;
class Hook extends Base {
@ -12,72 +13,35 @@ class Hook extends Base {
$sKey = $aParam['aArg'][1];
$iFromId = $aData["message"]["from"]["id"];
// 先清除,等于是覆盖,单进程
$r = ModelHook::where("tg_user_id", $iFromId)->delete();
ModelHook::where("tg_user_id", $iFromId)->truncate();
// 添加
$oHook = new ModelHook();
$oHook->tg_user_id = $iFromId;
$oHook->key = $sKey;
$oHook->steap = 1;
$r = $oHook->save();
if ($r) {
$aKey = explode(":", $sKey, 2);
// site类hook处理
if ($aKey[0] === "site") {
// $sSite = $aKey[0];
$sCode = $aKey[1];
$oSiteSingle = ModelSiteList::where("code", $sCode)->first();
if ($oSiteSingle) {
$r = "site::".$oSiteSingle->code."@".$oSiteSingle->www." | 就绪!";
} else {
$r = "没有这个site";
}
}
}
$oModelHook = new ModelHook();
$oModelHook->key = $sKey;
$oModelHook->tg_user_id = $iFromId;
$r = $oModelHook->save();
return $r;
}
public function go($aParam, $aData)
public function un($aParam, $aData)
{
// $aApiUrl =
$iFromId = $aData["message"]["from"]["id"];
ModelHook::where("tg_user_id", $iFromId)->truncate();
return $this->now($aParam, $aData);
}
public function now($aParam, $aData)
{
$iFromId = $aData["message"]["from"]["id"];
$sHookKey = ModelHook::where("tg_user_id", $iFromId)->first()?->key;
$oHookNow = ModelHook::where("tg_user_id", $iFromId)->first();
if ($oHookNow) {
$aHookNow = $oHookNow->toArray();
unset($aHookNow['id']);
unset($aHookNow['tg_user_id']);
$r = $this->toJson($aHookNow);
if ($sHookKey) {
$r = $sHookKey;
} else {
$r = "没有!";
$r = "hook未挂载";
}
return $r;
}
public function break($aParam, $aData)
{
$iFromId = $aData["message"]["from"]["id"];
$r = ModelHook::where("tg_user_id", $iFromId)->delete();
return $r;
}

View File

@ -0,0 +1,83 @@
<?php
namespace App\Services\TG\Hook\Mod;
use App\Models\Hook as ModelHook;
use App\Models\SiteList as ModelSiteList;
class Hook extends Base {
public function set($aParam, $aData)
{
$sKey = $aParam['aArg'][1];
$iFromId = $aData["message"]["from"]["id"];
// 先清除,等于是覆盖,单进程
$r = ModelHook::where("tg_user_id", $iFromId)->delete();
// 添加
$oHook = new ModelHook();
$oHook->tg_user_id = $iFromId;
$oHook->key = $sKey;
$oHook->steap = 1;
$r = $oHook->save();
if ($r) {
$aKey = explode(":", $sKey, 2);
// site类hook处理
if ($aKey[0] === "site") {
$sCode = $aKey[1];
$oSiteSingle = ModelSiteList::where("code", $sCode)->first();
if ($oSiteSingle) {
$r = "site::".$oSiteSingle->code."@".$oSiteSingle->www." | 就绪!";
} else {
$r = "没有这个site";
}
}
}
return $r;
}
public function go($aParam, $aData)
{
// $aApiUrl =
}
public function now($aParam, $aData)
{
$iFromId = $aData["message"]["from"]["id"];
$oHookNow = ModelHook::where("tg_user_id", $iFromId)->first();
if ($oHookNow) {
$aHookNow = $oHookNow->toArray();
unset($aHookNow['id']);
unset($aHookNow['tg_user_id']);
$r = $this->toJson($aHookNow);
} else {
$r = "没有!";
}
return $r;
}
public function break($aParam, $aData)
{
$iFromId = $aData["message"]["from"]["id"];
$r = ModelHook::where("tg_user_id", $iFromId)->delete();
return $r;
}
}

View File

@ -8,11 +8,14 @@ use App\Http\Controllers\ClientController;
use App\Http\Controllers\HelperController;
use App\Http\Controllers\HtmlController;
use App\Http\Controllers\SakaiController;
use App\Http\Controllers\CronController;
use App\Http\Controllers\Api\GithubController;
use App\Http\Controllers\Api\TG\HookController;
//Route::get('/', [ArticleListController::class, 'fn'])->middleware('test');
Route::get('/cron', [CronController::class, 'index']);
Route::get('/test1', [SakaiController::class, 'test1']);
Route::get('/test2', [SakaiController::class, 'test2']);
Route::get('/test3', [SakaiController::class, 'test3']);