225 lines
6.6 KiB
Dart
225 lines
6.6 KiB
Dart
/// Question type enum for text questions
|
||
enum QuestionType {
|
||
inspiration, // 启发类(包含"启发"关键词)
|
||
suggestion, // 建议类(包含"建议"、"意见"关键词)
|
||
overall, // 总体评价(zgpj)
|
||
general, // 通用类型
|
||
}
|
||
|
||
/// Metadata for questionnaire
|
||
class QuestionnaireMetadata {
|
||
final String title;
|
||
final String evaluatedPerson;
|
||
final String evaluationContent;
|
||
final String tokenValue;
|
||
final String questionnaireCode;
|
||
final String evaluatedPeopleNumber;
|
||
|
||
QuestionnaireMetadata({
|
||
required this.title,
|
||
required this.evaluatedPerson,
|
||
required this.evaluationContent,
|
||
required this.tokenValue,
|
||
required this.questionnaireCode,
|
||
required this.evaluatedPeopleNumber,
|
||
});
|
||
|
||
factory QuestionnaireMetadata.fromJson(Map<String, dynamic> json) {
|
||
return QuestionnaireMetadata(
|
||
title: json['title'] as String? ?? '',
|
||
evaluatedPerson: json['evaluatedPerson'] as String? ?? '',
|
||
evaluationContent: json['evaluationContent'] as String? ?? '',
|
||
tokenValue: json['tokenValue'] as String? ?? '',
|
||
questionnaireCode: json['questionnaireCode'] as String? ?? '',
|
||
evaluatedPeopleNumber: json['evaluatedPeopleNumber'] as String? ?? '',
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'title': title,
|
||
'evaluatedPerson': evaluatedPerson,
|
||
'evaluationContent': evaluationContent,
|
||
'tokenValue': tokenValue,
|
||
'questionnaireCode': questionnaireCode,
|
||
'evaluatedPeopleNumber': evaluatedPeopleNumber,
|
||
};
|
||
}
|
||
}
|
||
|
||
/// Radio option for single-choice questions
|
||
class RadioOption {
|
||
final String label; // 如"(A) 非常满意"
|
||
final String value; // 如"5_1"(5分×100%)
|
||
final double score; // 解析后的分数
|
||
final double weight; // 解析后的权重
|
||
|
||
RadioOption({
|
||
required this.label,
|
||
required this.value,
|
||
required this.score,
|
||
required this.weight,
|
||
});
|
||
|
||
factory RadioOption.fromJson(Map<String, dynamic> json) {
|
||
return RadioOption(
|
||
label: json['label'] as String? ?? '',
|
||
value: json['value'] as String? ?? '',
|
||
score: (json['score'] as num?)?.toDouble() ?? 0.0,
|
||
weight: (json['weight'] as num?)?.toDouble() ?? 0.0,
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {'label': label, 'value': value, 'score': score, 'weight': weight};
|
||
}
|
||
|
||
@override
|
||
String toString() {
|
||
return 'RadioOption(label: $label, value: $value, score: $score, weight: $weight)';
|
||
}
|
||
}
|
||
|
||
/// Radio question (single-choice question)
|
||
class RadioQuestion {
|
||
final String key; // 动态key,如"0000000401"
|
||
final String questionText; // 题目文本
|
||
final List<RadioOption> options;
|
||
final String category; // 如"师德师风"、"教学内容"
|
||
|
||
RadioQuestion({
|
||
required this.key,
|
||
required this.questionText,
|
||
required this.options,
|
||
this.category = '',
|
||
});
|
||
|
||
factory RadioQuestion.fromJson(Map<String, dynamic> json) {
|
||
return RadioQuestion(
|
||
key: json['key'] as String? ?? '',
|
||
questionText: json['questionText'] as String? ?? '',
|
||
options:
|
||
(json['options'] as List<dynamic>?)
|
||
?.map((e) => RadioOption.fromJson(e as Map<String, dynamic>))
|
||
.toList() ??
|
||
[],
|
||
category: json['category'] as String? ?? '',
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'key': key,
|
||
'questionText': questionText,
|
||
'options': options.map((e) => e.toJson()).toList(),
|
||
'category': category,
|
||
};
|
||
}
|
||
|
||
@override
|
||
String toString() {
|
||
return 'RadioQuestion(key: $key, questionText: $questionText, category: $category, options: ${options.length})';
|
||
}
|
||
}
|
||
|
||
/// Text question (open-ended question)
|
||
class TextQuestion {
|
||
final String key; // 动态key或"zgpj"
|
||
final String questionText; // 题目文本
|
||
final QuestionType type; // 通过关键词识别的类型
|
||
final bool isRequired; // 是否必填
|
||
|
||
TextQuestion({
|
||
required this.key,
|
||
required this.questionText,
|
||
required this.type,
|
||
this.isRequired = false,
|
||
});
|
||
|
||
factory TextQuestion.fromJson(Map<String, dynamic> json) {
|
||
return TextQuestion(
|
||
key: json['key'] as String? ?? '',
|
||
questionText: json['questionText'] as String? ?? '',
|
||
type: QuestionType.values.firstWhere(
|
||
(e) => e.toString() == 'QuestionType.${json['type']}',
|
||
orElse: () => QuestionType.general,
|
||
),
|
||
isRequired: json['isRequired'] as bool? ?? false,
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'key': key,
|
||
'questionText': questionText,
|
||
'type': type.toString().split('.').last,
|
||
'isRequired': isRequired,
|
||
};
|
||
}
|
||
|
||
@override
|
||
String toString() {
|
||
return 'TextQuestion(key: $key, questionText: $questionText, type: $type, isRequired: $isRequired)';
|
||
}
|
||
}
|
||
|
||
/// Complete questionnaire structure
|
||
class Questionnaire {
|
||
final QuestionnaireMetadata metadata;
|
||
final List<RadioQuestion> radioQuestions;
|
||
final List<TextQuestion> textQuestions;
|
||
final String tokenValue;
|
||
final String questionnaireCode;
|
||
final String evaluationContent;
|
||
final String evaluatedPeopleNumber;
|
||
|
||
Questionnaire({
|
||
required this.metadata,
|
||
required this.radioQuestions,
|
||
required this.textQuestions,
|
||
required this.tokenValue,
|
||
required this.questionnaireCode,
|
||
required this.evaluationContent,
|
||
required this.evaluatedPeopleNumber,
|
||
});
|
||
|
||
factory Questionnaire.fromJson(Map<String, dynamic> json) {
|
||
return Questionnaire(
|
||
metadata: QuestionnaireMetadata.fromJson(
|
||
json['metadata'] as Map<String, dynamic>? ?? {},
|
||
),
|
||
radioQuestions:
|
||
(json['radioQuestions'] as List<dynamic>?)
|
||
?.map((e) => RadioQuestion.fromJson(e as Map<String, dynamic>))
|
||
.toList() ??
|
||
[],
|
||
textQuestions:
|
||
(json['textQuestions'] as List<dynamic>?)
|
||
?.map((e) => TextQuestion.fromJson(e as Map<String, dynamic>))
|
||
.toList() ??
|
||
[],
|
||
tokenValue: json['tokenValue'] as String? ?? '',
|
||
questionnaireCode: json['questionnaireCode'] as String? ?? '',
|
||
evaluationContent: json['evaluationContent'] as String? ?? '',
|
||
evaluatedPeopleNumber: json['evaluatedPeopleNumber'] as String? ?? '',
|
||
);
|
||
}
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'metadata': metadata.toJson(),
|
||
'radioQuestions': radioQuestions.map((e) => e.toJson()).toList(),
|
||
'textQuestions': textQuestions.map((e) => e.toJson()).toList(),
|
||
'tokenValue': tokenValue,
|
||
'questionnaireCode': questionnaireCode,
|
||
'evaluationContent': evaluationContent,
|
||
'evaluatedPeopleNumber': evaluatedPeopleNumber,
|
||
};
|
||
}
|
||
|
||
@override
|
||
String toString() {
|
||
return 'Questionnaire(radioQuestions: ${radioQuestions.length}, textQuestions: ${textQuestions.length})';
|
||
}
|
||
}
|