feat: 实现用户画像、占卜历史与后端用户管理模块
This commit is contained in:
@@ -8,6 +8,7 @@ import '../../../../core/network/api_problem.dart';
|
||||
import '../../../../data/network/api_client.dart';
|
||||
import '../models/divination_backend_models.dart';
|
||||
import '../models/divination_params.dart';
|
||||
import '../models/divination_result.dart';
|
||||
|
||||
class DivinationApi {
|
||||
const DivinationApi({required ApiClient apiClient}) : _apiClient = apiClient;
|
||||
@@ -37,6 +38,67 @@ class DivinationApi {
|
||||
return RunAcceptedData.fromJson(json);
|
||||
}
|
||||
|
||||
Future<List<DivinationResultData>> getHistoryRecords({
|
||||
required String userId,
|
||||
}) async {
|
||||
final json = await _apiClient.getJson('/api/v1/agent/history');
|
||||
final messagesRaw = json['messages'];
|
||||
if (messagesRaw is! List<dynamic>) {
|
||||
return const <DivinationResultData>[];
|
||||
}
|
||||
|
||||
final records = <DivinationResultData>[];
|
||||
for (final raw in messagesRaw) {
|
||||
if (raw is! Map<String, dynamic>) {
|
||||
continue;
|
||||
}
|
||||
if (raw['role'] != 'assistant') {
|
||||
continue;
|
||||
}
|
||||
final agentOutputRaw = raw['agent_output'];
|
||||
if (agentOutputRaw is! Map<String, dynamic>) {
|
||||
continue;
|
||||
}
|
||||
final derivedRaw = agentOutputRaw['divination_derived'];
|
||||
if (derivedRaw is! Map<String, dynamic>) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
final derived = DerivedDivinationData.fromJson(derivedRaw);
|
||||
final divinationTime = _resolveHistoryTime(raw, derived);
|
||||
final params = DivinationParams(
|
||||
method: _methodFromText(derived.divinationMethod),
|
||||
questionType: _questionTypeFromText(derived.questionType),
|
||||
question: derived.question,
|
||||
divinationTime: divinationTime,
|
||||
coinBalance: 0,
|
||||
userId: userId,
|
||||
);
|
||||
final aggregate = DivinationRunAggregate(
|
||||
derived: derived,
|
||||
signLevel: _asString(agentOutputRaw['sign_level']),
|
||||
summary: _asString(agentOutputRaw['summary']),
|
||||
conclusion: _asStringList(agentOutputRaw['conclusion']),
|
||||
focusPoints: _asStringList(agentOutputRaw['focus_points']),
|
||||
advice: _asStringList(agentOutputRaw['advice']),
|
||||
keywords: _asStringList(agentOutputRaw['keywords']),
|
||||
answer: _asString(agentOutputRaw['answer']),
|
||||
);
|
||||
records.add(aggregate.toViewData(params));
|
||||
} catch (error, stackTrace) {
|
||||
_logger.warning(
|
||||
message: 'Skip malformed history assistant message',
|
||||
extra: <String, dynamic>{
|
||||
'error': error.toString(),
|
||||
'stackTrace': stackTrace.toString(),
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
Stream<Map<String, dynamic>> streamEvents({
|
||||
required String threadId,
|
||||
required String runId,
|
||||
@@ -217,6 +279,55 @@ String _questionTypeToText(QuestionType type) {
|
||||
};
|
||||
}
|
||||
|
||||
QuestionType _questionTypeFromText(String raw) {
|
||||
return switch (raw) {
|
||||
'事业' => QuestionType.career,
|
||||
'情感' => QuestionType.love,
|
||||
'财富' => QuestionType.wealth,
|
||||
'运势' => QuestionType.fortune,
|
||||
'解梦' => QuestionType.dream,
|
||||
'健康' => QuestionType.health,
|
||||
'学业' => QuestionType.study,
|
||||
'寻物' => QuestionType.search,
|
||||
_ => QuestionType.other,
|
||||
};
|
||||
}
|
||||
|
||||
DivinationMethod _methodFromText(String raw) {
|
||||
return raw == '自动起卦' ? DivinationMethod.auto : DivinationMethod.manual;
|
||||
}
|
||||
|
||||
DateTime _resolveHistoryTime(
|
||||
Map<String, dynamic> message,
|
||||
DerivedDivinationData derived,
|
||||
) {
|
||||
final timestamp = message['timestamp'];
|
||||
if (timestamp is String) {
|
||||
final parsed = DateTime.tryParse(timestamp);
|
||||
if (parsed != null) {
|
||||
return parsed.toLocal();
|
||||
}
|
||||
}
|
||||
|
||||
final derivedTime = DateTime.tryParse(derived.divinationTime);
|
||||
if (derivedTime != null) {
|
||||
return derivedTime.toLocal();
|
||||
}
|
||||
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
String _asString(Object? value) {
|
||||
return value is String ? value : '';
|
||||
}
|
||||
|
||||
List<String> _asStringList(Object? value) {
|
||||
if (value is! List<dynamic>) {
|
||||
return const <String>[];
|
||||
}
|
||||
return value.whereType<String>().toList(growable: false);
|
||||
}
|
||||
|
||||
String _yaoTypeToText(YaoType type) {
|
||||
return switch (type) {
|
||||
YaoType.youngYang => '少阳',
|
||||
|
||||
Reference in New Issue
Block a user