feat: 实现用户画像、占卜历史与后端用户管理模块
This commit is contained in:
@@ -60,6 +60,21 @@ class DivinationParams {
|
||||
};
|
||||
}
|
||||
|
||||
factory DivinationParams.fromPayload(Map<String, dynamic> payload) {
|
||||
return DivinationParams(
|
||||
method: divinationMethodFromName(_requiredString(payload, 'method')),
|
||||
questionType: questionTypeFromName(
|
||||
_requiredString(payload, 'questionType'),
|
||||
),
|
||||
question: _requiredString(payload, 'question'),
|
||||
divinationTime: DateTime.parse(
|
||||
_requiredString(payload, 'divinationTime'),
|
||||
),
|
||||
coinBalance: _requiredInt(payload, 'coinBalance'),
|
||||
userId: _requiredString(payload, 'userId'),
|
||||
);
|
||||
}
|
||||
|
||||
String toBinary(List<YaoType> yaoStates) {
|
||||
return yaoStates
|
||||
.map(
|
||||
@@ -85,3 +100,43 @@ class DivinationParams {
|
||||
.join();
|
||||
}
|
||||
}
|
||||
|
||||
DivinationMethod divinationMethodFromName(String raw) {
|
||||
return DivinationMethod.values.firstWhere(
|
||||
(value) => value.name == raw,
|
||||
orElse: () => DivinationMethod.manual,
|
||||
);
|
||||
}
|
||||
|
||||
QuestionType questionTypeFromName(String raw) {
|
||||
return QuestionType.values.firstWhere(
|
||||
(value) => value.name == raw,
|
||||
orElse: () => QuestionType.other,
|
||||
);
|
||||
}
|
||||
|
||||
YaoType yaoTypeFromName(String raw) {
|
||||
return YaoType.values.firstWhere(
|
||||
(value) => value.name == raw,
|
||||
orElse: () => YaoType.undetermined,
|
||||
);
|
||||
}
|
||||
|
||||
String _requiredString(Map<String, dynamic> json, String key) {
|
||||
final value = json[key];
|
||||
if (value is! String || value.isEmpty) {
|
||||
throw FormatException('Missing required string: $key');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int _requiredInt(Map<String, dynamic> json, String key) {
|
||||
final value = json[key];
|
||||
if (value is int) {
|
||||
return value;
|
||||
}
|
||||
if (value is num) {
|
||||
return value.toInt();
|
||||
}
|
||||
throw FormatException('Missing required int: $key');
|
||||
}
|
||||
|
||||
@@ -38,6 +38,79 @@ class DivinationResultData {
|
||||
final List<YaoLineData> targetYaoLines;
|
||||
|
||||
bool get hasChangingYao => binaryCode != changedBinaryCode;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return <String, dynamic>{
|
||||
'params': params.toPayload(),
|
||||
'binaryCode': binaryCode,
|
||||
'changedBinaryCode': changedBinaryCode,
|
||||
'guaName': guaName,
|
||||
'targetGuaName': targetGuaName,
|
||||
'upperName': upperName,
|
||||
'lowerName': lowerName,
|
||||
'signType': signType,
|
||||
'keywords': keywords,
|
||||
'conclusion': conclusion,
|
||||
'analysis': analysis,
|
||||
'suggestion': suggestion,
|
||||
'ganzhi': ganzhi.toJson(),
|
||||
'wuXingStatus': wuXingStatus,
|
||||
'yaoLines': yaoLines.map((line) => line.toJson()).toList(growable: false),
|
||||
'targetYaoLines': targetYaoLines
|
||||
.map((line) => line.toJson())
|
||||
.toList(growable: false),
|
||||
};
|
||||
}
|
||||
|
||||
factory DivinationResultData.fromJson(Map<String, dynamic> json) {
|
||||
final paramsRaw = json['params'];
|
||||
final ganzhiRaw = json['ganzhi'];
|
||||
final wuXingRaw = json['wuXingStatus'];
|
||||
final yaoLinesRaw = json['yaoLines'];
|
||||
final targetYaoLinesRaw = json['targetYaoLines'];
|
||||
if (paramsRaw is! Map<String, dynamic> ||
|
||||
ganzhiRaw is! Map<String, dynamic> ||
|
||||
wuXingRaw is! Map<String, dynamic> ||
|
||||
yaoLinesRaw is! List<dynamic> ||
|
||||
targetYaoLinesRaw is! List<dynamic>) {
|
||||
throw const FormatException('Invalid divination result payload');
|
||||
}
|
||||
|
||||
return DivinationResultData(
|
||||
params: DivinationParams.fromPayload(paramsRaw),
|
||||
binaryCode: _requiredString(json, 'binaryCode'),
|
||||
changedBinaryCode: _requiredString(json, 'changedBinaryCode'),
|
||||
guaName: _requiredString(json, 'guaName'),
|
||||
targetGuaName: _requiredString(json, 'targetGuaName'),
|
||||
upperName: _requiredString(json, 'upperName'),
|
||||
lowerName: _requiredString(json, 'lowerName'),
|
||||
signType: _requiredString(json, 'signType'),
|
||||
keywords: _requiredString(json, 'keywords'),
|
||||
conclusion: _requiredString(json, 'conclusion'),
|
||||
analysis: _requiredString(json, 'analysis'),
|
||||
suggestion: _requiredString(json, 'suggestion'),
|
||||
ganzhi: GanzhiData.fromJson(ganzhiRaw),
|
||||
wuXingStatus: wuXingRaw.map(
|
||||
(key, value) => MapEntry(key, value.toString()),
|
||||
),
|
||||
yaoLines: yaoLinesRaw
|
||||
.map((raw) {
|
||||
if (raw is! Map<String, dynamic>) {
|
||||
throw const FormatException('Invalid yao line payload');
|
||||
}
|
||||
return YaoLineData.fromJson(raw);
|
||||
})
|
||||
.toList(growable: false),
|
||||
targetYaoLines: targetYaoLinesRaw
|
||||
.map((raw) {
|
||||
if (raw is! Map<String, dynamic>) {
|
||||
throw const FormatException('Invalid target yao line payload');
|
||||
}
|
||||
return YaoLineData.fromJson(raw);
|
||||
})
|
||||
.toList(growable: false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GanzhiData {
|
||||
@@ -68,6 +141,40 @@ class GanzhiData {
|
||||
final String riChen;
|
||||
final String yuePo;
|
||||
final String riChong;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return <String, dynamic>{
|
||||
'yearGanZhi': yearGanZhi,
|
||||
'monthGanZhi': monthGanZhi,
|
||||
'dayGanZhi': dayGanZhi,
|
||||
'timeGanZhi': timeGanZhi,
|
||||
'yearKongWang': yearKongWang,
|
||||
'monthKongWang': monthKongWang,
|
||||
'dayKongWang': dayKongWang,
|
||||
'timeKongWang': timeKongWang,
|
||||
'yueJian': yueJian,
|
||||
'riChen': riChen,
|
||||
'yuePo': yuePo,
|
||||
'riChong': riChong,
|
||||
};
|
||||
}
|
||||
|
||||
factory GanzhiData.fromJson(Map<String, dynamic> json) {
|
||||
return GanzhiData(
|
||||
yearGanZhi: _requiredString(json, 'yearGanZhi'),
|
||||
monthGanZhi: _requiredString(json, 'monthGanZhi'),
|
||||
dayGanZhi: _requiredString(json, 'dayGanZhi'),
|
||||
timeGanZhi: _requiredString(json, 'timeGanZhi'),
|
||||
yearKongWang: _requiredString(json, 'yearKongWang'),
|
||||
monthKongWang: _requiredString(json, 'monthKongWang'),
|
||||
dayKongWang: _requiredString(json, 'dayKongWang'),
|
||||
timeKongWang: _requiredString(json, 'timeKongWang'),
|
||||
yueJian: _requiredString(json, 'yueJian'),
|
||||
riChen: _requiredString(json, 'riChen'),
|
||||
yuePo: _requiredString(json, 'yuePo'),
|
||||
riChong: _requiredString(json, 'riChong'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class YaoLineData {
|
||||
@@ -88,4 +195,47 @@ class YaoLineData {
|
||||
final String element;
|
||||
final YaoType type;
|
||||
final String mark;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return <String, dynamic>{
|
||||
'index': index,
|
||||
'spirit': spirit,
|
||||
'relation': relation,
|
||||
'branch': branch,
|
||||
'element': element,
|
||||
'type': type.name,
|
||||
'mark': mark,
|
||||
};
|
||||
}
|
||||
|
||||
factory YaoLineData.fromJson(Map<String, dynamic> json) {
|
||||
return YaoLineData(
|
||||
index: _requiredInt(json, 'index'),
|
||||
spirit: _requiredString(json, 'spirit'),
|
||||
relation: _requiredString(json, 'relation'),
|
||||
branch: _requiredString(json, 'branch'),
|
||||
element: _requiredString(json, 'element'),
|
||||
type: yaoTypeFromName(_requiredString(json, 'type')),
|
||||
mark: _requiredString(json, 'mark'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _requiredString(Map<String, dynamic> json, String key) {
|
||||
final value = json[key];
|
||||
if (value is! String || value.isEmpty) {
|
||||
throw FormatException('Missing required string: $key');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int _requiredInt(Map<String, dynamic> json, String key) {
|
||||
final value = json[key];
|
||||
if (value is int) {
|
||||
return value;
|
||||
}
|
||||
if (value is num) {
|
||||
return value.toInt();
|
||||
}
|
||||
throw FormatException('Missing required int: $key');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user