chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
@@ -0,0 +1,79 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace ywxapp\middleware;
use think\facade\Config;
use ywxapp\service\AddonPerformanceMonitor;
/**
* 插件性能监控中间件(全局注册于 app/middleware.php
*
* 设计要点:
* - 从请求路径首段解析插件名(插件路由统一为 /<插件名>/<group>/...),
* 仅对「已启用插件」的请求做性能采样,核心应用(admin/index/api 等)零开销;
* - 用 AddonPerformanceMonitor::measure() 包裹 $next($request),把每次插件
* HTTP 请求的真实耗时/内存/成功失败写入缓存,使 addon:health 的性能项有真数据;
* - measure() 的 finally 已防御性吞掉缓存异常,本中间件无需再包 try/catch,
* 且绝不二次调用 $next(避免重复执行业务);
* - 控制器抛异常时 measure() 记录为失败并原样向外抛出,框架错误处理不受影响。
*
* @author ywxapp <admin@ywxapp.cn>
*/
class AddonPerformanceMiddleware
{
public function handle($request, \Closure $next)
{
$addon = $this->resolveAddon($request);
if ($addon === null) {
return $next($request);
}
$action = $this->resolveAction($request);
return AddonPerformanceMonitor::measure($addon, $action, function () use ($next, $request) {
return $next($request);
});
}
/**
* 从路径首段解析插件名,并确认其为已启用插件(Config::get('addon') 仅含 state=1
*/
private function resolveAddon($request): ?string
{
$path = trim((string) $request->pathinfo(), '/');
if ($path === '') {
return null;
}
$segments = explode('/', $path);
$maybe = $segments[0];
$addon = Config::get('addon', []);
foreach ($addon as $info) {
if (($info['name'] ?? '') === $maybe) {
return $maybe;
}
}
return null;
}
/**
* 动作标签:HTTP 方法 + 插件名之后的剩余路径(如 GET backend/addonreview/index
*/
private function resolveAction($request): string
{
$path = trim((string) $request->pathinfo(), '/');
$segments = explode('/', $path);
array_shift($segments); // 去掉插件名首段
$rest = implode('/', $segments);
return ($request->method() ?? 'GET') . ' ' . ($rest === '' ? 'index' : $rest);
}
}