feat(admin): XHProf 采样列表页

- curd -t ul_xhprof_run 生成三件套(控制器 xhprof.run 子目录形态,model docblock 随生成刷新)
- 只读化:toolbar 清空 + 行内仅详情按钮(open 弹层 xhprof.run/detail?id=N,auth=detail),
  add/edit/delete 等 action 保留靠权限节点不分配拦截(T8 对齐)
- 列渲染:wall_time/cpu_time μs→ms(>1000ms 红色)、memory_peak 字节→MB、
  url 截断 title 全显、method 标签化、request_time 浮点秒→日期时间
- 四组搜索:url like / request_time range / wall_time 下限(前端 ms,后端换算 μs,
  withGet 全量合并写回)/ node_id 下拉(DISTINCT + data_brage 通道)
- 生成前 scheme:sync 修复 request_time 的 null/comment 漂移(T3 手工 ALTER 遗留)
This commit is contained in:
augushong
2026-08-15 06:48:45 +08:00
parent a43a9a48b9
commit e57b186126
11 changed files with 489 additions and 10 deletions

View File

@@ -0,0 +1,81 @@
<?php
namespace app\admin\controller\xhprof;
use app\common\controller\AdminController;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use think\App;
/**
* XHProf 性能采样记录(只读列表)
* 数据由定时任务从 jsonl 导入,后台仅查看与函数级分析,不支持手动增删改。
*
* @ControllerAnnotation(title="XHProf 性能采样记录")
*/
class Run extends AdminController
{
use \app\admin\traits\Curd;
protected $sort = [
'request_time' => 'desc',
];
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new \app\admin\model\XhprofRun();
}
/**
* @NodeAnotation(title="列表")
*/
public function index()
{
if ($this->request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
// wall_time 搜索下限:前端输入毫秒,换算为微秒后再构建查询条件
// 注意Request::withGet 是整体替换,必须先取全量 GET 再合并写回
$filter = (string) $this->request->get('filter', '');
if ($filter !== '') {
$filterArr = json_decode($filter, true) ?: [];
if (isset($filterArr['wall_time']) && $filterArr['wall_time'] !== '') {
$filterArr['wall_time'] = (string) ((float) $filterArr['wall_time'] * 1000);
$this->request->withGet(array_merge($this->request->get(), [
'filter' => json_encode($filterArr, JSON_UNESCAPED_UNICODE),
]));
}
}
list($page, $limit, $where, $excludes, $request_options, $group) = $this->buildTableParames();
$count = $this->model
->where($where)
->group($group)
->count();
$list = $this->model
->where($where)
->page($page, $limit)
->order($this->sort)
->group($group)
->select();
$data = [
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $list,
];
return json($data);
}
// 节点下拉选项(多节点环境区分数据来源)
$nodeIds = $this->model->distinct(true)->column('node_id');
$nodeSelect = array_combine($nodeIds, $nodeIds) ?: [];
$this->assign('select_list_node_id', $nodeSelect, true);
return $this->fetch();
}
}