APP_NEW/lib/Class/Result/posture_issue_result.dart
2025-03-11 21:17:14 +08:00

552 lines
20 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:lamiter/Class/Diagnosis/posture_issue.dart';
import 'package:lamiter/Class/Diagnosis/symptom.dart';
import 'package:lamiter/Provider/Diagnosis/Diagnosis_Item/posture_issue_provider.dart';
import 'package:lamiter/Provider/Diagnosis/Diagnosis_Item/symptom_provider.dart';
import 'package:provider/provider.dart';
class PostureIssueResult {
String? id;
int? head_tilt_score;
int? forward_head_posture_score;
int? uneven_shoulders_score;
int? rounded_shoulders_score;
int? pelvic_tilt_score;
int? spinal_misalignment_score;
int? hyperextended_knee_score;
int? right_leg_shape_score;
int? left_leg_shape_score;
String? right_leg_shape_note;
String? left_leg_shape_note;
List<String>? front_muscles;
List<String>? front_muscles_note;
List<String>? side_muscles;
List<String>? side_muscles_note;
List<String>? back_muscles;
List<String>? back_muscles_note;
List<String>? zang_fu_organs;
List<String>? meridians;
num? head_tilt_angle;
num? forward_head_posture_angle;
num? uneven_shoulders_angle;
num? rounded_shoulders_angle;
num? pelvic_tilt_angle;
num? spinal_misalignment_angle;
num? hyperextended_knee_angle;
num? right_thigh_angle;
num? right_calf_angle;
num? left_thigh_angle;
num? left_calf_angle;
PostureIssueResult({
// 體態症狀
this.head_tilt_score,
this.forward_head_posture_score,
this.uneven_shoulders_score,
this.rounded_shoulders_score,
this.pelvic_tilt_score,
this.spinal_misalignment_score,
this.hyperextended_knee_score,
this.right_leg_shape_score,
this.left_leg_shape_score,
this.right_leg_shape_note,
this.left_leg_shape_note,
// 體態角度
this.head_tilt_angle,
this.forward_head_posture_angle,
this.uneven_shoulders_angle,
this.rounded_shoulders_angle,
this.pelvic_tilt_angle,
this.spinal_misalignment_angle,
this.hyperextended_knee_angle,
this.right_thigh_angle,
this.right_calf_angle,
this.left_thigh_angle,
this.left_calf_angle,
// 肌肉
this.front_muscles,
this.front_muscles_note,
this.side_muscles,
this.side_muscles_note,
this.back_muscles,
this.back_muscles_note,
// 臟腑
this.zang_fu_organs,
// 經絡
this.meridians,
});
PostureIssueResult.fromJson(Map<String, dynamic> json)
: head_tilt_score = json['head_tilt_score'] as int?,
forward_head_posture_score = json['forward_head_posture_score'] as int?,
uneven_shoulders_score = json['uneven_shoulders_score'] as int?,
rounded_shoulders_score = json['rounded_shoulders_score'] as int?,
pelvic_tilt_score = json['pelvic_tilt_score'] as int?,
spinal_misalignment_score = json['spinal_misalignment_score'] as int?,
hyperextended_knee_score = json['hyperextended_knee_score'] as int?,
right_leg_shape_score = json['right_leg_shape_score'] as int?,
left_leg_shape_score = json['left_leg_shape_score'] as int?,
right_leg_shape_note = json['right_leg_shape_note'] as String?,
left_leg_shape_note = json['left_leg_shape_note'] as String?,
front_muscles = (json['front_muscles'] as List<dynamic>?)
?.map((muscle) => muscle as String)
.toList(),
front_muscles_note = (json['front_muscles_note'] as List<dynamic>?)
?.map((note) => note as String)
.toList(),
side_muscles = (json['side_muscles'] as List<dynamic>?)
?.map((muscle) => muscle as String)
.toList(),
side_muscles_note = (json['side_muscles_note'] as List<dynamic>?)
?.map((note) => note as String)
.toList(),
back_muscles = (json['back_muscles'] as List<dynamic>?)
?.map((muscle) => muscle as String)
.toList(),
back_muscles_note = (json['back_muscles_note'] as List<dynamic>?)
?.map((note) => note as String)
.toList(),
zang_fu_organs = (json['zang_fu_organs'] as List<dynamic>?)
?.map((organ) => organ as String)
.toList(),
meridians = (json['meridians'] as List<dynamic>?)
?.map((meridian) => meridian as String)
.toList(),
head_tilt_angle = json['head_tilt_angle'] as num?,
forward_head_posture_angle = json['forward_head_posture_angle'] as num?,
uneven_shoulders_angle = json['uneven_shoulders_angle'] as num?,
rounded_shoulders_angle = json['rounded_shoulders_angle'] as num?,
pelvic_tilt_angle = json['pelvic_tilt_angle'] as num?,
spinal_misalignment_angle = json['spinal_misalignment_angle'] as num?,
hyperextended_knee_angle = json['hyperextended_knee_angle'] as num?,
right_thigh_angle = json['right_thigh_angle'] as num?,
right_calf_angle = json['right_calf_angle'] as num?,
left_thigh_angle = json['left_thigh_angle'] as num?,
left_calf_angle = json['left_calf_angle'] as num?;
Map<String, dynamic> toJson() => {
'head_tilt_score': head_tilt_score,
'forward_head_posture_score': forward_head_posture_score,
'uneven_shoulders_score': uneven_shoulders_score,
'rounded_shoulders_score': rounded_shoulders_score,
'pelvic_tilt_score': pelvic_tilt_score,
'spinal_misalignment_score': spinal_misalignment_score,
'hyperextended_knee_score': hyperextended_knee_score,
'right_leg_shape_score': right_leg_shape_score,
'left_leg_shape_score': left_leg_shape_score,
'right_leg_shape_note': right_leg_shape_note,
'left_leg_shape_note': left_leg_shape_note,
'head_tilt_angle': head_tilt_angle,
'forward_head_posture_angle': forward_head_posture_angle,
'uneven_shoulders_angle': uneven_shoulders_angle,
'rounded_shoulders_angle': rounded_shoulders_angle,
'pelvic_tilt_angle': pelvic_tilt_angle,
'spinal_misalignment_angle': spinal_misalignment_angle,
'hyperextended_knee_angle': hyperextended_knee_angle,
'right_thigh_angle': right_thigh_angle,
'right_calf_angle': right_calf_angle,
'left_thigh_angle': left_thigh_angle,
'left_calf_angle': left_calf_angle,
'front_muscles': front_muscles,
'front_muscles_note': front_muscles_note,
'side_muscles': side_muscles,
'side_muscles_note': side_muscles_note,
'back_muscles': back_muscles,
'back_muscles_note': back_muscles_note,
'zang_fu_organs': zang_fu_organs,
'meridians': meridians,
};
void debug() {
print(head_tilt_score);
print(forward_head_posture_score);
print(uneven_shoulders_score);
print(rounded_shoulders_score);
print(pelvic_tilt_score);
print(spinal_misalignment_score);
print(hyperextended_knee_score);
print(right_leg_shape_score);
print(left_leg_shape_score);
}
List<Color> posture_issue_status_colors = [
Colors.green,
Colors.amber,
Colors.red
];
List<String> posture_issue_status_labels = ['輕度', '中度', '重度'];
final int posture_issue_low_threshold = 50;
final int posture_issue_high_threshold = 75;
String posture_issue_label(PostureIssue postureIssue) {
return posture_issue_status_labels[
_posture_issue_status(posture_issue_score(postureIssue))];
}
Color posture_issue_color(PostureIssue postureIssue) {
return posture_issue_status_colors[
_posture_issue_status(posture_issue_score(postureIssue))];
}
List<Symptom> posture_issue_symptoms(
BuildContext context, PostureIssue postureIssue) {
List<Symptom> temp = [];
for (var id in postureIssue.relatedSymptomsIds) {
final symptom = context.read<SymptomProvider>().findWithId(id);
if (symptom != null) temp.add(symptom);
}
return temp;
}
String posture_issue_angle_note(PostureIssue postureIssue) {
switch (postureIssue.id) {
case 'head_tilt':
return head_tilt_angle != null
? _left_right_angle_note(head_tilt_angle!)
: '';
case 'forward_head_posture':
return forward_head_posture_angle != null
? _angle_note(forward_head_posture_angle!)
: '';
case 'uneven_shoulders':
return uneven_shoulders_angle != null
? _left_right_angle_note(uneven_shoulders_angle!)
: '';
case 'rounded_shoulders':
return rounded_shoulders_angle != null
? _angle_note(rounded_shoulders_angle!)
: '';
case 'pelvic_tilt':
return pelvic_tilt_angle != null
? _left_right_angle_note(pelvic_tilt_angle!)
: '';
case 'spinal_misalignment':
return spinal_misalignment_angle != null
? _angle_note(spinal_misalignment_angle!)
: '';
case 'hyperextended_knee':
return hyperextended_knee_angle != null
? _angle_note(hyperextended_knee_angle!)
: '';
case 'left_o_legs':
return _left_leg_angle_note();
case 'left_x_legs':
return _left_leg_angle_note();
case 'left_xo_legs':
return _left_leg_angle_note();
case 'right_o_legs':
return _right_leg_angle_note();
case 'right_x_legs':
return _right_leg_angle_note();
case 'right_xo_legs':
return _right_leg_angle_note();
default:
return '';
}
}
Widget posture_issue_image_widget(PostureIssue postureIssue, double height) {
String assetHeader = 'assets/x_ray';
String fileExtension = '.png';
String imagePath = '';
bool flip = false;
try {
if (posture_issue_score(postureIssue) >= posture_issue_high_threshold) {
imagePath = '$assetHeader/${postureIssue.id}/high_risk$fileExtension';
if (postureIssue.id.contains('o_legs')) {
imagePath = '$assetHeader/o_legs/high_risk$fileExtension';
}
if (postureIssue.id.contains('x_legs')) {
imagePath = '$assetHeader/x_legs/high_risk$fileExtension';
}
if (postureIssue.id.contains('xo_legs')) {
imagePath = '$assetHeader/xo_legs/high_risk$fileExtension';
}
} else if ((postureIssue.id == 'head_tilt' ||
postureIssue.id == 'pelvic_tilt' ||
postureIssue.id == 'uneven_shoulders') &&
posture_issue_score(postureIssue) >= posture_issue_low_threshold) {
imagePath = '$assetHeader/${postureIssue.id}/medium_risk$fileExtension';
} else {
imagePath = '$assetHeader/${postureIssue.id}/normal$fileExtension';
if (postureIssue.id.contains('o_legs')) {
imagePath = '$assetHeader/o_legs/normal$fileExtension';
}
if (postureIssue.id.contains('x_legs')) {
imagePath = '$assetHeader/x_legs/normal$fileExtension';
}
if (postureIssue.id.contains('xo_legs')) {
imagePath = '$assetHeader/xo_legs/normal$fileExtension';
}
}
} catch (e) {
imagePath = 'assets/default_error.png';
}
if (postureIssue.id == 'head_tilt') {
flip = (head_tilt_angle ?? 0) > 0;
}
if (postureIssue.id == 'uneven_shoulders') {
flip = (uneven_shoulders_angle ?? 0) < 0;
}
if (postureIssue.id == 'pelvic_tilt') {
flip = (pelvic_tilt_angle ?? 0) > 0;
}
return Transform.flip(
flipX: flip,
child: Container(
height: height,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(5),
image: DecorationImage(
image: AssetImage(imagePath),
fit: BoxFit.contain,
),
),
),
);
}
String _left_right_angle_note(num angle) {
if (angle > 0) {
return '(向左傾 $angle 度)';
} else {
return '(向右傾 ${angle.abs()} 度)';
}
}
String _angle_note(num angle) {
return '(傾斜 ${angle.abs()} 度)';
}
String _left_leg_angle_note() {
return '(左大腿傾斜 ${left_thigh_angle?.abs()} 度,左小腿傾斜 ${left_calf_angle?.abs()} 度)';
}
String _right_leg_angle_note() {
return '(右大腿傾斜 ${right_thigh_angle?.abs()} 度,右小腿傾斜 ${right_calf_angle?.abs()} 度)';
}
int posture_issue_score(PostureIssue postureIssue) {
switch (postureIssue.id) {
case 'head_tilt':
return head_tilt_score ?? 0;
case 'forward_head_posture':
return forward_head_posture_score ?? 0;
case 'uneven_shoulders':
return uneven_shoulders_score ?? 0;
case 'rounded_shoulders':
return rounded_shoulders_score ?? 0;
case 'pelvic_tilt':
return pelvic_tilt_score ?? 0;
case 'spinal_misalignment':
return spinal_misalignment_score ?? 0;
case 'hyperextended_knee':
return hyperextended_knee_score ?? 0;
case 'left_o_legs':
return left_leg_shape_score ?? 0;
case 'left_x_legs':
return left_leg_shape_score ?? 0;
case 'left_xo_legs':
return left_leg_shape_score ?? 0;
case 'right_o_legs':
return right_leg_shape_score ?? 0;
case 'right_x_legs':
return right_leg_shape_score ?? 0;
case 'right_xo_legs':
return right_leg_shape_score ?? 0;
default:
return -1;
}
}
int _posture_issue_status(int score) {
if (score < 0) return -1;
if (score < posture_issue_low_threshold) return 0;
if (score < posture_issue_high_threshold) return 1;
return 2;
}
List<PostureIssue> screenshot_should_display_posture_issue(
BuildContext context) {
final postureIssues = context.read<PostureIssueProvider>().elements;
var temp = postureIssues
.where((postureIssue) =>
_posture_issue_status(posture_issue_score(postureIssue)) > 0)
.toList();
// leg, ignoring...
final o_legs = context.read<PostureIssueProvider>().findWithId('o_legs');
final x_legs = context.read<PostureIssueProvider>().findWithId('x_legs');
final xo_legs = context.read<PostureIssueProvider>().findWithId('xo_legs');
if (left_leg_shape_score != null &&
_posture_issue_status(left_leg_shape_score!) > 0) {
final left_legs_posture_issue = left_leg_shape_note == 'O'
? o_legs
: left_leg_shape_note == 'X'
? x_legs
: xo_legs;
final leftLegsPostureIssue = PostureIssue(
id: 'left_' + (left_legs_posture_issue?.id ?? ''),
name: '左腿腿型(${left_legs_posture_issue?.name ?? ''}',
relatedSymptomsIds: left_legs_posture_issue?.relatedSymptomsIds ?? [],
);
temp.add(leftLegsPostureIssue);
}
if (right_leg_shape_score != null &&
_posture_issue_status(right_leg_shape_score!) > 0) {
final right_legs_posture_issue = right_leg_shape_note == 'O'
? o_legs
: right_leg_shape_note == 'X'
? x_legs
: xo_legs;
final rightLegsPostureIssue = PostureIssue(
id: 'right_' + (right_legs_posture_issue?.id ?? ''),
name: '右腿腿型(${right_legs_posture_issue?.name ?? ''}',
relatedSymptomsIds: right_legs_posture_issue?.relatedSymptomsIds ?? [],
);
temp.add(rightLegsPostureIssue);
}
return temp;
}
List<PostureIssue> report_display_posture_issues(BuildContext context) {
final postureIssues = context.read<PostureIssueProvider>().elements;
var temp = postureIssues
.where((postureIssue) =>
_posture_issue_status(posture_issue_score(postureIssue)) > -1)
.toList();
// leg, ignoring...
final o_legs = context.read<PostureIssueProvider>().findWithId('o_legs');
final x_legs = context.read<PostureIssueProvider>().findWithId('x_legs');
final xo_legs = context.read<PostureIssueProvider>().findWithId('xo_legs');
// if (left_leg_shape_score != null &&
// _posture_issue_status(left_leg_shape_score!) > 1) {
final left_legs_posture_issue = left_leg_shape_note == 'O'
? o_legs
: left_leg_shape_note == 'X'
? x_legs
: xo_legs;
final leftLegsPostureIssue = PostureIssue(
id: 'left_' + (left_legs_posture_issue?.id ?? ''),
name: '左腿腿型(${left_legs_posture_issue?.name ?? ''}',
relatedSymptomsIds: left_legs_posture_issue?.relatedSymptomsIds ?? [],
);
temp.add(leftLegsPostureIssue);
// }
// if (right_leg_shape_score != null &&
// _posture_issue_status(right_leg_shape_score!) > 1) {
final right_legs_posture_issue = right_leg_shape_note == 'O'
? o_legs
: right_leg_shape_note == 'X'
? x_legs
: xo_legs;
final rightLegsPostureIssue = PostureIssue(
id: 'right_' + (right_legs_posture_issue?.id ?? ''),
name: '右腿腿型(${right_legs_posture_issue?.name ?? ''}',
relatedSymptomsIds: right_legs_posture_issue?.relatedSymptomsIds ?? [],
);
temp.add(rightLegsPostureIssue);
// }
return temp;
}
List<PostureIssue> risk_posture_issues(BuildContext context) {
final postureIssues = context.read<PostureIssueProvider>().elements;
var temp = postureIssues
.where((postureIssue) =>
_posture_issue_status(posture_issue_score(postureIssue)) > 0)
.toSet();
// leg, ignoring...
if (left_leg_shape_score != null &&
_posture_issue_status(left_leg_shape_score!) > 0) {
if (left_leg_shape_note == 'O')
temp.add(context.read<PostureIssueProvider>().findWithId('o_legs')!);
if (left_leg_shape_note == 'X')
temp.add(context.read<PostureIssueProvider>().findWithId('x_legs')!);
if (left_leg_shape_note == 'XO')
temp.add(context.read<PostureIssueProvider>().findWithId('xo_legs')!);
}
if (right_leg_shape_score != null &&
_posture_issue_status(right_leg_shape_score!) > 0) {
if (right_leg_shape_note == 'O')
temp.add(context.read<PostureIssueProvider>().findWithId('o_legs')!);
if (right_leg_shape_note == 'X')
temp.add(context.read<PostureIssueProvider>().findWithId('x_legs')!);
if (right_leg_shape_note == 'XO')
temp.add(context.read<PostureIssueProvider>().findWithId('xo_legs')!);
}
return temp.toList();
}
int muscles_status_length = 3;
List<String> muscles_status_labels = ['視情況而定', '需放鬆', '需加強'];
List<Color> muscles_status_colors = [
Color(0xff9DDDF7),
Colors.amber,
Colors.red
];
int? trend_posture_issue_score(PostureIssue postureIssue) {
switch (postureIssue.id) {
case 'head_tilt':
return head_tilt_score;
case 'forward_head_posture':
return forward_head_posture_score;
case 'uneven_shoulders':
return uneven_shoulders_score;
case 'rounded_shoulders':
return rounded_shoulders_score;
case 'pelvic_tilt':
return pelvic_tilt_score;
case 'spinal_misalignment':
return spinal_misalignment_score;
case 'hyperextended_knee':
return hyperextended_knee_score;
case 'o_legs':
int? left_leg_score =
(left_leg_shape_note == 'O') ? left_leg_shape_score : null;
int? right_leg_score =
(right_leg_shape_note == 'O') ? right_leg_shape_score : null;
if (left_leg_score == null || right_leg_score == null) {
if (left_leg_score != null) return left_leg_score;
if (right_leg_score != null) return right_leg_score;
return null;
}
return max(left_leg_score, right_leg_score);
case 'x_legs':
int? left_leg_score =
(left_leg_shape_note == 'X') ? left_leg_shape_score : null;
int? right_leg_score =
(right_leg_shape_note == 'X') ? right_leg_shape_score : null;
if (left_leg_score == null || right_leg_score == null) {
if (left_leg_score != null) return left_leg_score;
if (right_leg_score != null) return right_leg_score;
return null;
}
return max(left_leg_score, right_leg_score);
case 'xo_legs':
int? left_leg_score =
(left_leg_shape_note == 'XO') ? left_leg_shape_score : null;
int? right_leg_score =
(right_leg_shape_note == 'XO') ? right_leg_shape_score : null;
if (left_leg_score == null || right_leg_score == null) {
if (left_leg_score != null) return left_leg_score;
if (right_leg_score != null) return right_leg_score;
return null;
}
return max(left_leg_score, right_leg_score);
default:
return null;
}
}
}