马良AI写作初始化仓库
This commit is contained in:
702
AINoval/lib/models/admin/llm_observability_models.dart
Normal file
702
AINoval/lib/models/admin/llm_observability_models.dart
Normal file
@@ -0,0 +1,702 @@
|
||||
/// LLM可观测性相关数据模型
|
||||
/// 用于管理后台查看和分析大模型调用日志
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import '../../utils/date_time_parser.dart';
|
||||
|
||||
part 'llm_observability_models.g.dart';
|
||||
|
||||
/// 自定义时间戳转换器
|
||||
class TimestampConverter implements JsonConverter<DateTime, dynamic> {
|
||||
const TimestampConverter();
|
||||
|
||||
@override
|
||||
DateTime fromJson(dynamic timestamp) {
|
||||
return parseBackendDateTime(timestamp);
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic toJson(DateTime timestamp) {
|
||||
return timestamp.toIso8601String();
|
||||
}
|
||||
}
|
||||
|
||||
/// LLM调用日志
|
||||
@JsonSerializable()
|
||||
class LLMTrace extends Equatable {
|
||||
final String id;
|
||||
final String traceId;
|
||||
final String provider;
|
||||
final String model;
|
||||
final String? userId;
|
||||
final String? sessionId;
|
||||
@JsonKey(name: 'createdAt')
|
||||
@TimestampConverter()
|
||||
final DateTime timestamp;
|
||||
|
||||
// 请求信息
|
||||
final LLMRequest request;
|
||||
|
||||
// 响应信息
|
||||
final LLMResponse? response;
|
||||
|
||||
// 性能指标
|
||||
final LLMPerformanceMetrics? performance;
|
||||
|
||||
// 错误信息
|
||||
final LLMError? error;
|
||||
|
||||
// 工具调用
|
||||
final List<LLMToolCall>? toolCalls;
|
||||
|
||||
// 元数据
|
||||
final Map<String, dynamic>? metadata;
|
||||
|
||||
// 状态
|
||||
@JsonKey(defaultValue: LLMTraceStatus.pending)
|
||||
final LLMTraceStatus status;
|
||||
@JsonKey(defaultValue: false)
|
||||
final bool isStreaming;
|
||||
|
||||
const LLMTrace({
|
||||
required this.id,
|
||||
required this.traceId,
|
||||
required this.provider,
|
||||
required this.model,
|
||||
this.userId,
|
||||
this.sessionId,
|
||||
required this.timestamp,
|
||||
required this.request,
|
||||
this.response,
|
||||
this.performance,
|
||||
this.error,
|
||||
this.toolCalls,
|
||||
this.metadata,
|
||||
this.status = LLMTraceStatus.pending,
|
||||
this.isStreaming = false,
|
||||
});
|
||||
|
||||
factory LLMTrace.fromJson(Map<String, dynamic> json) => _$LLMTraceFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMTraceToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, traceId, provider, model, userId, sessionId, timestamp, request, response, performance, error, toolCalls, metadata, status, isStreaming];
|
||||
}
|
||||
|
||||
/// LLM请求信息
|
||||
@JsonSerializable()
|
||||
class LLMRequest extends Equatable {
|
||||
final List<LLMMessage>? messages;
|
||||
|
||||
// 模型参数
|
||||
final double? temperature;
|
||||
final double? topP;
|
||||
final int? topK;
|
||||
final int? maxTokens;
|
||||
final int? seed;
|
||||
|
||||
// 工具调用
|
||||
final List<LLMTool>? tools;
|
||||
final String? toolChoice;
|
||||
|
||||
// 格式设置
|
||||
final String? responseFormat;
|
||||
|
||||
// 其他参数
|
||||
final Map<String, dynamic>? additionalParameters;
|
||||
|
||||
const LLMRequest({
|
||||
this.messages,
|
||||
this.temperature,
|
||||
this.topP,
|
||||
this.topK,
|
||||
this.maxTokens,
|
||||
this.seed,
|
||||
this.tools,
|
||||
this.toolChoice,
|
||||
this.responseFormat,
|
||||
this.additionalParameters,
|
||||
});
|
||||
|
||||
factory LLMRequest.fromJson(Map<String, dynamic> json) => _$LLMRequestFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMRequestToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [messages, temperature, topP, topK, maxTokens, seed, tools, toolChoice, responseFormat, additionalParameters];
|
||||
}
|
||||
|
||||
/// LLM响应信息
|
||||
@JsonSerializable()
|
||||
class LLMResponse extends Equatable {
|
||||
final String? id;
|
||||
final String? content;
|
||||
|
||||
// Token使用情况
|
||||
final LLMTokenUsage? tokenUsage;
|
||||
|
||||
// 完成原因
|
||||
final String? finishReason;
|
||||
|
||||
// 工具调用结果
|
||||
final List<LLMToolCallResult>? toolCallResults;
|
||||
|
||||
// 元数据
|
||||
final Map<String, dynamic>? metadata;
|
||||
|
||||
// 流式数据
|
||||
final List<String>? streamChunks;
|
||||
|
||||
const LLMResponse({
|
||||
this.id,
|
||||
this.content,
|
||||
this.tokenUsage,
|
||||
this.finishReason,
|
||||
this.toolCallResults,
|
||||
this.metadata,
|
||||
this.streamChunks,
|
||||
});
|
||||
|
||||
factory LLMResponse.fromJson(Map<String, dynamic> json) => _$LLMResponseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMResponseToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, content, tokenUsage, finishReason, toolCallResults, metadata, streamChunks];
|
||||
}
|
||||
|
||||
/// LLM消息
|
||||
@JsonSerializable()
|
||||
class LLMMessage extends Equatable {
|
||||
final String role;
|
||||
final String? content;
|
||||
final String? name;
|
||||
final Map<String, dynamic>? metadata;
|
||||
|
||||
const LLMMessage({
|
||||
required this.role,
|
||||
this.content,
|
||||
this.name,
|
||||
this.metadata,
|
||||
});
|
||||
|
||||
factory LLMMessage.fromJson(Map<String, dynamic> json) => _$LLMMessageFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMMessageToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [role, content, name, metadata];
|
||||
}
|
||||
|
||||
/// LLM工具定义
|
||||
@JsonSerializable()
|
||||
class LLMTool extends Equatable {
|
||||
final String name;
|
||||
final String? description;
|
||||
final Map<String, dynamic>? parameters;
|
||||
|
||||
const LLMTool({
|
||||
required this.name,
|
||||
this.description,
|
||||
this.parameters,
|
||||
});
|
||||
|
||||
factory LLMTool.fromJson(Map<String, dynamic> json) => _$LLMToolFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMToolToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [name, description, parameters];
|
||||
}
|
||||
|
||||
/// LLM工具调用
|
||||
@JsonSerializable()
|
||||
class LLMToolCall extends Equatable {
|
||||
final String id;
|
||||
final String name;
|
||||
final Map<String, dynamic>? arguments;
|
||||
final DateTime? timestamp;
|
||||
|
||||
const LLMToolCall({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.arguments,
|
||||
this.timestamp,
|
||||
});
|
||||
|
||||
factory LLMToolCall.fromJson(Map<String, dynamic> json) => _$LLMToolCallFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMToolCallToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, name, arguments, timestamp];
|
||||
}
|
||||
|
||||
/// LLM工具调用结果
|
||||
@JsonSerializable()
|
||||
class LLMToolCallResult extends Equatable {
|
||||
final String toolCallId;
|
||||
final String? result;
|
||||
final LLMError? error;
|
||||
|
||||
const LLMToolCallResult({
|
||||
required this.toolCallId,
|
||||
this.result,
|
||||
this.error,
|
||||
});
|
||||
|
||||
factory LLMToolCallResult.fromJson(Map<String, dynamic> json) => _$LLMToolCallResultFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMToolCallResultToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [toolCallId, result, error];
|
||||
}
|
||||
|
||||
/// Token使用情况
|
||||
@JsonSerializable()
|
||||
class LLMTokenUsage extends Equatable {
|
||||
final int? promptTokens;
|
||||
final int? completionTokens;
|
||||
final int? totalTokens;
|
||||
|
||||
// 详细分解
|
||||
final int? inputTokens;
|
||||
final int? outputTokens;
|
||||
final int? reasoningTokens;
|
||||
final int? cachedTokens;
|
||||
|
||||
const LLMTokenUsage({
|
||||
this.promptTokens,
|
||||
this.completionTokens,
|
||||
this.totalTokens,
|
||||
this.inputTokens,
|
||||
this.outputTokens,
|
||||
this.reasoningTokens,
|
||||
this.cachedTokens,
|
||||
});
|
||||
|
||||
factory LLMTokenUsage.fromJson(Map<String, dynamic> json) => _$LLMTokenUsageFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMTokenUsageToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [promptTokens, completionTokens, totalTokens, inputTokens, outputTokens, reasoningTokens, cachedTokens];
|
||||
}
|
||||
|
||||
/// 性能指标
|
||||
@JsonSerializable()
|
||||
class LLMPerformanceMetrics extends Equatable {
|
||||
final int? requestLatencyMs;
|
||||
final int? firstTokenLatencyMs;
|
||||
final int? totalDurationMs;
|
||||
|
||||
// 吞吐量
|
||||
final double? tokensPerSecond;
|
||||
final double? charactersPerSecond;
|
||||
|
||||
// 队列时间
|
||||
final int? queueTimeMs;
|
||||
final int? processingTimeMs;
|
||||
|
||||
const LLMPerformanceMetrics({
|
||||
this.requestLatencyMs,
|
||||
this.firstTokenLatencyMs,
|
||||
this.totalDurationMs,
|
||||
this.tokensPerSecond,
|
||||
this.charactersPerSecond,
|
||||
this.queueTimeMs,
|
||||
this.processingTimeMs,
|
||||
});
|
||||
|
||||
factory LLMPerformanceMetrics.fromJson(Map<String, dynamic> json) => _$LLMPerformanceMetricsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMPerformanceMetricsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [requestLatencyMs, firstTokenLatencyMs, totalDurationMs, tokensPerSecond, charactersPerSecond, queueTimeMs, processingTimeMs];
|
||||
}
|
||||
|
||||
/// 错误信息
|
||||
@JsonSerializable()
|
||||
class LLMError extends Equatable {
|
||||
final String? type;
|
||||
final String? message;
|
||||
final String? code;
|
||||
final String? stackTrace;
|
||||
final Map<String, dynamic>? details;
|
||||
|
||||
const LLMError({
|
||||
this.type,
|
||||
this.message,
|
||||
this.code,
|
||||
this.stackTrace,
|
||||
this.details,
|
||||
});
|
||||
|
||||
factory LLMError.fromJson(Map<String, dynamic> json) => _$LLMErrorFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMErrorToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [type, message, code, stackTrace, details];
|
||||
}
|
||||
|
||||
/// LLM调用状态
|
||||
enum LLMTraceStatus {
|
||||
@JsonValue('pending')
|
||||
pending,
|
||||
@JsonValue('success')
|
||||
success,
|
||||
@JsonValue('error')
|
||||
error,
|
||||
@JsonValue('timeout')
|
||||
timeout,
|
||||
@JsonValue('cancelled')
|
||||
cancelled,
|
||||
}
|
||||
|
||||
/// 统计信息基类
|
||||
@JsonSerializable()
|
||||
class LLMStatistics extends Equatable {
|
||||
final int totalCalls;
|
||||
final int successfulCalls;
|
||||
final int failedCalls;
|
||||
final double successRate;
|
||||
final double averageLatency;
|
||||
final int totalTokens;
|
||||
|
||||
// 时间范围
|
||||
final DateTime? startTime;
|
||||
final DateTime? endTime;
|
||||
|
||||
// 详细统计
|
||||
final Map<String, dynamic>? details;
|
||||
|
||||
const LLMStatistics({
|
||||
required this.totalCalls,
|
||||
required this.successfulCalls,
|
||||
required this.failedCalls,
|
||||
required this.successRate,
|
||||
required this.averageLatency,
|
||||
required this.totalTokens,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.details,
|
||||
});
|
||||
|
||||
factory LLMStatistics.fromJson(Map<String, dynamic> json) => _$LLMStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [totalCalls, successfulCalls, failedCalls, successRate, averageLatency, totalTokens, startTime, endTime, details];
|
||||
}
|
||||
|
||||
/// 提供商统计
|
||||
@JsonSerializable()
|
||||
class ProviderStatistics extends Equatable {
|
||||
final String provider;
|
||||
final LLMStatistics statistics;
|
||||
final List<ModelStatistics> models;
|
||||
|
||||
const ProviderStatistics({
|
||||
required this.provider,
|
||||
required this.statistics,
|
||||
required this.models,
|
||||
});
|
||||
|
||||
factory ProviderStatistics.fromJson(Map<String, dynamic> json) => _$ProviderStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ProviderStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [provider, statistics, models];
|
||||
}
|
||||
|
||||
/// 模型统计
|
||||
@JsonSerializable()
|
||||
class ModelStatistics extends Equatable {
|
||||
final String modelName;
|
||||
final String provider;
|
||||
final LLMStatistics statistics;
|
||||
|
||||
const ModelStatistics({
|
||||
required this.modelName,
|
||||
required this.provider,
|
||||
required this.statistics,
|
||||
});
|
||||
|
||||
factory ModelStatistics.fromJson(Map<String, dynamic> json) => _$ModelStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ModelStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [modelName, provider, statistics];
|
||||
}
|
||||
|
||||
/// 用户统计
|
||||
@JsonSerializable()
|
||||
class UserStatistics extends Equatable {
|
||||
final String userId;
|
||||
final String? username;
|
||||
final LLMStatistics statistics;
|
||||
final List<String> topModels;
|
||||
final List<String> topProviders;
|
||||
|
||||
const UserStatistics({
|
||||
required this.userId,
|
||||
this.username,
|
||||
required this.statistics,
|
||||
required this.topModels,
|
||||
required this.topProviders,
|
||||
});
|
||||
|
||||
factory UserStatistics.fromJson(Map<String, dynamic> json) => _$UserStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$UserStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [userId, username, statistics, topModels, topProviders];
|
||||
}
|
||||
|
||||
/// 错误统计
|
||||
@JsonSerializable()
|
||||
class ErrorStatistics extends Equatable {
|
||||
final String errorType;
|
||||
final int count;
|
||||
final double percentage;
|
||||
final List<String> topErrorMessages;
|
||||
final List<String> affectedModels;
|
||||
|
||||
const ErrorStatistics({
|
||||
required this.errorType,
|
||||
required this.count,
|
||||
required this.percentage,
|
||||
required this.topErrorMessages,
|
||||
required this.affectedModels,
|
||||
});
|
||||
|
||||
factory ErrorStatistics.fromJson(Map<String, dynamic> json) => _$ErrorStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ErrorStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [errorType, count, percentage, topErrorMessages, affectedModels];
|
||||
}
|
||||
|
||||
/// 性能统计
|
||||
@JsonSerializable()
|
||||
class PerformanceStatistics extends Equatable {
|
||||
final double averageLatency;
|
||||
final double medianLatency;
|
||||
final double p95Latency;
|
||||
final double p99Latency;
|
||||
final double averageThroughput;
|
||||
|
||||
// 按时间分组的统计
|
||||
final List<TimeBasedMetric> latencyTrends;
|
||||
final List<TimeBasedMetric> throughputTrends;
|
||||
|
||||
const PerformanceStatistics({
|
||||
required this.averageLatency,
|
||||
required this.medianLatency,
|
||||
required this.p95Latency,
|
||||
required this.p99Latency,
|
||||
required this.averageThroughput,
|
||||
required this.latencyTrends,
|
||||
required this.throughputTrends,
|
||||
});
|
||||
|
||||
factory PerformanceStatistics.fromJson(Map<String, dynamic> json) => _$PerformanceStatisticsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$PerformanceStatisticsToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [averageLatency, medianLatency, p95Latency, p99Latency, averageThroughput, latencyTrends, throughputTrends];
|
||||
}
|
||||
|
||||
/// 基于时间的指标
|
||||
@JsonSerializable()
|
||||
class TimeBasedMetric extends Equatable {
|
||||
final DateTime timestamp;
|
||||
final double value;
|
||||
final String? label;
|
||||
|
||||
const TimeBasedMetric({
|
||||
required this.timestamp,
|
||||
required this.value,
|
||||
this.label,
|
||||
});
|
||||
|
||||
factory TimeBasedMetric.fromJson(Map<String, dynamic> json) => _$TimeBasedMetricFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$TimeBasedMetricToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [timestamp, value, label];
|
||||
}
|
||||
|
||||
/// 系统健康状态
|
||||
@JsonSerializable()
|
||||
class SystemHealthStatus extends Equatable {
|
||||
@JsonKey(defaultValue: HealthStatus.healthy)
|
||||
final HealthStatus status;
|
||||
final Map<String, ComponentHealth> components;
|
||||
final String? message;
|
||||
final DateTime? lastChecked;
|
||||
|
||||
const SystemHealthStatus({
|
||||
this.status = HealthStatus.healthy,
|
||||
required this.components,
|
||||
this.message,
|
||||
this.lastChecked,
|
||||
});
|
||||
|
||||
factory SystemHealthStatus.fromJson(Map<String, dynamic> json) => _$SystemHealthStatusFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$SystemHealthStatusToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [status, components, message, lastChecked];
|
||||
}
|
||||
|
||||
/// 组件健康状态
|
||||
@JsonSerializable()
|
||||
class ComponentHealth extends Equatable {
|
||||
@JsonKey(defaultValue: HealthStatus.healthy)
|
||||
final HealthStatus status;
|
||||
final String? message;
|
||||
final Map<String, dynamic>? metrics;
|
||||
|
||||
const ComponentHealth({
|
||||
this.status = HealthStatus.healthy,
|
||||
this.message,
|
||||
this.metrics,
|
||||
});
|
||||
|
||||
factory ComponentHealth.fromJson(Map<String, dynamic> json) => _$ComponentHealthFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ComponentHealthToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [status, message, metrics];
|
||||
}
|
||||
|
||||
/// 健康状态枚举
|
||||
enum HealthStatus {
|
||||
@JsonValue('healthy')
|
||||
healthy,
|
||||
@JsonValue('degraded')
|
||||
degraded,
|
||||
@JsonValue('unhealthy')
|
||||
unhealthy,
|
||||
@JsonValue('unknown')
|
||||
unknown,
|
||||
}
|
||||
|
||||
/// LLM日志搜索条件
|
||||
@JsonSerializable()
|
||||
class LLMTraceSearchCriteria extends Equatable {
|
||||
final String? userId;
|
||||
final String? provider;
|
||||
final String? model;
|
||||
final String? sessionId;
|
||||
final bool? hasError;
|
||||
final LLMTraceStatus? status;
|
||||
final DateTime? startTime;
|
||||
final DateTime? endTime;
|
||||
|
||||
// 分页
|
||||
@JsonKey(defaultValue: 0)
|
||||
final int page;
|
||||
@JsonKey(defaultValue: 20)
|
||||
final int size;
|
||||
@JsonKey(defaultValue: 'timestamp')
|
||||
final String sortBy;
|
||||
@JsonKey(defaultValue: 'desc')
|
||||
final String sortDir;
|
||||
|
||||
const LLMTraceSearchCriteria({
|
||||
this.userId,
|
||||
this.provider,
|
||||
this.model,
|
||||
this.sessionId,
|
||||
this.hasError,
|
||||
this.status,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.page = 0,
|
||||
this.size = 20,
|
||||
this.sortBy = 'timestamp',
|
||||
this.sortDir = 'desc',
|
||||
});
|
||||
|
||||
factory LLMTraceSearchCriteria.fromJson(Map<String, dynamic> json) => _$LLMTraceSearchCriteriaFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$LLMTraceSearchCriteriaToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [userId, provider, model, sessionId, hasError, status, startTime, endTime, page, size, sortBy, sortDir];
|
||||
}
|
||||
|
||||
/// API响应包装类
|
||||
@JsonSerializable(genericArgumentFactories: true)
|
||||
class ApiResponse<T> extends Equatable {
|
||||
final bool success;
|
||||
final String? message;
|
||||
final T? data;
|
||||
final String? error;
|
||||
|
||||
const ApiResponse({
|
||||
required this.success,
|
||||
this.message,
|
||||
this.data,
|
||||
this.error,
|
||||
});
|
||||
|
||||
factory ApiResponse.fromJson(Map<String, dynamic> json, T Function(Object? json) fromJsonT) =>
|
||||
_$ApiResponseFromJson(json, fromJsonT);
|
||||
Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
|
||||
_$ApiResponseToJson(this, toJsonT);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [success, message, data, error];
|
||||
}
|
||||
|
||||
/// 分页响应
|
||||
@JsonSerializable(genericArgumentFactories: true)
|
||||
class PagedResponse<T> extends Equatable {
|
||||
final List<T> content;
|
||||
final int page;
|
||||
final int size;
|
||||
final int totalElements;
|
||||
final int totalPages;
|
||||
@JsonKey(defaultValue: false)
|
||||
final bool first;
|
||||
@JsonKey(defaultValue: false)
|
||||
final bool last;
|
||||
|
||||
const PagedResponse({
|
||||
required this.content,
|
||||
required this.page,
|
||||
required this.size,
|
||||
required this.totalElements,
|
||||
required this.totalPages,
|
||||
this.first = false,
|
||||
this.last = false,
|
||||
});
|
||||
|
||||
factory PagedResponse.fromJson(Map<String, dynamic> json, T Function(Object? json) fromJsonT) =>
|
||||
_$PagedResponseFromJson(json, fromJsonT);
|
||||
Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
|
||||
_$PagedResponseToJson(this, toJsonT);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [content, page, size, totalElements, totalPages, first, last];
|
||||
}
|
||||
|
||||
/// 游标分页响应
|
||||
@JsonSerializable(genericArgumentFactories: true)
|
||||
class CursorPageResponse<T> extends Equatable {
|
||||
final List<T> items;
|
||||
final String? nextCursor;
|
||||
@JsonKey(defaultValue: false)
|
||||
final bool hasMore;
|
||||
|
||||
const CursorPageResponse({
|
||||
required this.items,
|
||||
this.nextCursor,
|
||||
this.hasMore = false,
|
||||
});
|
||||
|
||||
factory CursorPageResponse.fromJson(Map<String, dynamic> json, T Function(Object? json) fromJsonT) =>
|
||||
_$CursorPageResponseFromJson(json, fromJsonT);
|
||||
Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
|
||||
_$CursorPageResponseToJson(this, toJsonT);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [items, nextCursor, hasMore];
|
||||
}
|
||||
Reference in New Issue
Block a user