column('id', 'ID')->sortable();
$grid->column('user.username', '用户名');
$grid->column('user_id', '用户ID');
$grid->column('message', '日志消息')
->limit(50)
->help('用户操作的详细描述');
$grid->column('source_type', '来源类型')
->display(function ($value) {
if (!$value) {
return '未知';
}
// 处理枚举实例或字符串
$typeValue = $value instanceof REWARD_SOURCE_TYPE ? $value->value : $value;
// 使用枚举获取名称和信息
if (REWARD_SOURCE_TYPE::isValid($typeValue)) {
$info = REWARD_SOURCE_TYPE::getTypeInfo($typeValue);
$name = $info['name'];
$icon = $info['icon'];
$category = $info['category'];
// 根据分类设置标签颜色
$labelColors = [
'gameplay' => 'primary',
'event' => 'warning',
'daily' => 'info',
'achievement' => 'success',
'progression' => 'success',
'farm' => 'warning',
'social' => 'info',
'shop' => 'primary',
'promotion' => 'danger',
'competition' => 'success',
'special' => 'warning',
'system' => 'default',
'unknown' => 'default'
];
$color = $labelColors[$category] ?? 'default';
return "{$icon} {$name}";
}
return "{$value}";
});
$grid->column('source_id', '来源ID');
$grid->column('source_table', '来源表名')
->limit(20)
->display(function ($value) {
// 使用原始的、未截断的值
$originalValue = $this->source_table;
if (!$originalValue || !$this->source_id) {
return $value;
}
// 获取对应的后台管理页面URL
$url = self::getSourceDetailUrl($originalValue, $this->source_id);
if ($url) {
return "" .
" {$value}";
}
return $value;
});
$grid->column('created_at', '创建时间')
->sortable();
// 筛选器
$grid->filter(function (Grid\Filter $filter) {
$filter->equal('user_id', '用户ID');
$filter->like('message', '日志消息');
// 使用枚举生成来源类型选项
$sourceTypeOptions = [];
foreach (REWARD_SOURCE_TYPE::cases() as $case) {
$info = REWARD_SOURCE_TYPE::getTypeInfo($case->value);
$sourceTypeOptions[$case->value] = $info['icon'] . ' ' . $info['name'];
}
$filter->equal('source_type', '来源类型')
->select($sourceTypeOptions);
$filter->between('created_at', '创建时间')->datetime();
});
// 默认排序
$grid->model()->orderBy('created_at', 'desc');
// 禁用创建按钮
$grid->disableCreateButton();
// 禁用编辑
$grid->disableEditButton();
// 批量操作
$grid->batchActions(function (Grid\Tools\BatchActions $batch) {
// 暂时注释掉批量删除功能,避免误删重要日志
// $batch->add('清理选中日志', new \App\Module\Game\AdminControllers\Actions\BatchDeleteUserLogsAction());
});
// 工具栏
$grid->tools(function (Grid\Tools $tools) {
// 暂时注释掉工具按钮,避免类不存在错误
// $tools->append(new \App\Module\Game\AdminControllers\Tools\CleanExpiredLogsButton());
// $tools->append(new \App\Module\Game\AdminControllers\Tools\UserLogStatsButton());
});
});
}
/**
* Make a show builder.
*
* @param mixed $id
* @return Show
*/
protected function detail($id)
{
return Show::make($id, UserLog::with(['user']), function (Show $show) {
$show->field('id', 'ID');
$show->field('user.username', '用户名');
$show->field('user_id', '用户ID');
$show->field('message', '日志消息')
->unescape();
$show->field('source_type', '来源类型')
->as(function ($value) {
if (!$value) {
return '未知';
}
// 处理枚举实例或字符串
$typeValue = $value instanceof REWARD_SOURCE_TYPE ? $value->value : $value;
if (REWARD_SOURCE_TYPE::isValid($typeValue)) {
$info = REWARD_SOURCE_TYPE::getTypeInfo($typeValue);
return $info['icon'] . ' ' . $info['name'] . ' (' . $info['description'] . ')';
}
return $value;
});
$show->field('source_id', '来源ID');
$show->field('source_table', '来源表名');
$show->field('created_at', '创建时间');
// 禁用编辑和删除按钮
$show->disableEditButton();
$show->disableDeleteButton();
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(UserLog::class, function (Form $form) {
$form->display('id', 'ID');
$form->number('user_id', '用户ID')
->required()
->help('关联的用户ID');
$form->textarea('message', '日志消息')
->required()
->rows(3)
->help('用户操作的详细描述');
// 使用枚举生成来源类型选项
$sourceTypeOptions = [];
foreach (REWARD_SOURCE_TYPE::cases() as $case) {
$info = REWARD_SOURCE_TYPE::getTypeInfo($case->value);
$sourceTypeOptions[$case->value] = $info['icon'] . ' ' . $info['name'];
}
$form->select('source_type', '来源类型')
->options($sourceTypeOptions)
->help('日志来源的模块类型,使用标准化的奖励来源枚举');
$form->number('source_id', '来源ID')
->help('关联的业务记录ID');
$form->text('source_table', '来源表名')
->help('关联的数据库表名');
$form->display('created_at', '创建时间');
// 禁用删除按钮
$form->disableDeleteButton();
});
}
/**
* 获取来源详情页面URL
*
* @param string $sourceTable 来源表名
* @param int $sourceId 来源记录ID
* @return string|null 详情页面URL,null表示无对应页面
*/
public static function getSourceDetailUrl(string $sourceTable, int $sourceId): ?string
{
// 来源表名到后台路由的映射关系
$tableRouteMap = [
'fund_logs' => 'fund-logs',
'item_transaction_logs' => 'game-items-transaction-logs',
'farm_harvest_logs' => 'farm-harvest-logs',
'farm_upgrade_logs' => 'farm-upgrade-logs',
'pet_battle_logs' => 'pet-battle-logs',
'pet_skill_logs' => 'pet-skill-logs',
'task_reward_logs' => 'task-reward-logs',
'task_reset_logs' => 'task-reset-logs',
'game_items_dismantle_logs' => 'game-items-dismantle-logs',
'system_logs' => 'system-logs',
];
// 检查是否有对应的路由
if (!isset($tableRouteMap[$sourceTable])) {
return null;
}
$route = $tableRouteMap[$sourceTable];
// 生成详情页面URL
return admin_url("{$route}/{$sourceId}");
}
/**
* 清理过期日志
*
* @return \Illuminate\Http\JsonResponse
*/
public function cleanExpiredLogs()
{
try {
$days = request('days', 30);
$deletedCount = UserLogService::cleanExpiredLogs($days);
return response()->json([
'status' => true,
'message' => "成功清理 {$deletedCount} 条过期日志",
]);
} catch (\Exception $e) {
return response()->json([
'status' => false,
'message' => '清理过期日志失败:' . $e->getMessage(),
]);
}
}
/**
* 获取用户日志统计信息
*
* @return \Illuminate\Http\JsonResponse
*/
public function getStats()
{
try {
$userId = request('user_id');
if (!$userId) {
return response()->json([
'status' => false,
'message' => '请提供用户ID',
]);
}
$stats = UserLogService::getUserLogStats($userId);
return response()->json([
'status' => true,
'data' => $stats,
]);
} catch (\Exception $e) {
return response()->json([
'status' => false,
'message' => '获取统计信息失败:' . $e->getMessage(),
]);
}
}
}