mobile_measure_view.dart 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import 'package:fis_i18n/i18n.dart';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  4. import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
  5. import 'package:fis_measure/process/layout/configuration.dart';
  6. import 'package:fis_measure/process/workspace/measure_controller.dart';
  7. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  8. import 'package:fis_measure/process/workspace/measure_handler.dart';
  9. import 'package:fis_measure/view/gesture/positioned_touch_cursor.dart';
  10. import 'package:fis_measure/view/mobile_view/mobile_measure_main_view.dart';
  11. import 'package:fis_ui/index.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:get/get.dart';
  14. import 'package:flutter/services.dart';
  15. /// 测量主页面
  16. class MobileMeasureMainPage extends StatefulWidget implements FWidget {
  17. const MobileMeasureMainPage(
  18. this.token,
  19. this.recordCode,
  20. this.patientCode,
  21. this.remedicalCode,
  22. this.remedicalAISelectedInfoCode, {
  23. this.isCanWriteReport = false,
  24. this.onEditReport,
  25. Key? key,
  26. }) : super(key: key);
  27. final String token;
  28. final String patientCode;
  29. final String remedicalCode;
  30. final String recordCode;
  31. final String? remedicalAISelectedInfoCode;
  32. final bool isCanWriteReport;
  33. final void Function()? onEditReport;
  34. @override
  35. State<StatefulWidget> createState() => _MobileMeasureMainPageState();
  36. }
  37. class _MobileMeasureMainPageState extends State<MobileMeasureMainPage> {
  38. /// 数据
  39. final measureData = Get.find<MeasureDataController>();
  40. String _remedicalCode = '';
  41. late final application = Get.find<IApplication>();
  42. // final mouseState = Get.put<IMouseState>(MouseState());
  43. /// 页面loadding
  44. bool loaded = false;
  45. // /// 图片loadding
  46. late bool imageLoaded = false;
  47. ///检查图片信息表
  48. List<ExamImageInfo> examImageInfoList = [];
  49. late final measureHandler = Get.find<IMeasureHandler>();
  50. /// 测量控制器
  51. late MeasureController measureController = Get.put(MeasureController(
  52. "",
  53. imagesFetchFunc: (code) async {
  54. return examImageInfoList;
  55. },
  56. ));
  57. /// 获取测量图片所需的图片组 并且写入控制器中 加载
  58. void getExamImageInfoList(List<RemedicalInfoDTO> remedicals) async {
  59. examImageInfoList = remedicals.map((e) {
  60. final imgInfo = e.terminalImages!;
  61. final vidUrl = measureData.chooseImageUrl(imgInfo);
  62. return ExamImageInfo(vidUrl, imgInfo.previewUrl!);
  63. }).toList();
  64. measureController = Get.put(MeasureController(
  65. "",
  66. imagesFetchFunc: (code) async {
  67. return examImageInfoList;
  68. },
  69. ));
  70. await measureController.load();
  71. final selectedImageIndex = examImageInfoList.indexWhere(
  72. (element) => element.url == measureData.itemCurrentImage,
  73. );
  74. if (selectedImageIndex > -1) {
  75. // 命中当前选择图像
  76. measureController.examInfo.selectedImageIndex = selectedImageIndex;
  77. }
  78. }
  79. void changeImage(sender, e) {
  80. imageLoaded = e;
  81. setState(() {});
  82. }
  83. /// 初始化卡尺样式部分
  84. Future<void> _initTouchModuel() async {
  85. Get.put<ITouchPointState>(TouchPointState());
  86. }
  87. @override
  88. void initState() {
  89. _remedicalCode = widget.remedicalCode;
  90. _initTouchModuel();
  91. SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
  92. SystemChrome.setSystemUIChangeCallback((systemOverlaysAreVisible) async {
  93. await Future.delayed(const Duration(seconds: 1));
  94. SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
  95. });
  96. measureHandler.onChangeImageLoaded.addListener(changeImage);
  97. measureHandler.changeImageByIndex.addListener(changeImageByIndex);
  98. loadLayoutConfig();
  99. getImageInfo();
  100. initDefaultMeasureSystemSetting();
  101. super.initState();
  102. }
  103. /// 初始化默认用户设置
  104. void initDefaultMeasureSystemSetting() {
  105. final defaultMobileMeasureSystemSetting = MeasureSystemSettingDTO(
  106. cursorSize: 16,
  107. shapeCursorSize: 30,
  108. showResultWindow: true,
  109. fontSize: 14,
  110. showCursorLine: true,
  111. showDepthGuideline: true,
  112. showBriefAnnotation: true,
  113. autoSnapDistance: '20',
  114. minCursorDistance: '20',
  115. annotationFontSize: 14,
  116. );
  117. measureData.measureSystemSetting = defaultMobileMeasureSystemSetting;
  118. }
  119. void getImageInfo() {
  120. measureData.measureImageData = MeasureImageData(
  121. patientCode: widget.patientCode,
  122. recordCode: widget.recordCode,
  123. remedicalCode: _remedicalCode,
  124. );
  125. }
  126. /// 加载图像布局配置
  127. void loadLayoutConfig() async {
  128. await LayoutConfiguration.ins.loadData();
  129. setState(() {
  130. // 加载图像数据
  131. _initData();
  132. });
  133. }
  134. void onImageLoaded(Object sender, ExamImageInfo? e) async {
  135. // measureHandler.changeImageLoaded = true;
  136. if (!mounted) return;
  137. final currentImage = measureData.remedicalList.firstWhereOrNull(
  138. (element) =>
  139. element.terminalImages!.imageUrl == e!.url ||
  140. element.terminalImages!.originImageUrl == e.url,
  141. );
  142. if (currentImage != null) {
  143. /// 获取图片详细信息
  144. var remedicalInfo = await measureData.getImageInfo(
  145. currentImage.remedicalCode ?? '',
  146. widget.token,
  147. widget.remedicalAISelectedInfoCode,
  148. );
  149. if (remedicalInfo != null) {
  150. measureData.aiResults = remedicalInfo.diagnosisResult ?? '';
  151. /// ai 良恶性 判断是否有ai
  152. measureData.diagnosisConclusion = remedicalInfo.diagnosisConclusion;
  153. if (remedicalInfo.carotidResult != null) {
  154. } else {}
  155. try {
  156. if (e != null) {
  157. Future.delayed(const Duration(milliseconds: 100), () {
  158. measureController.playerController.play();
  159. });
  160. setState(() {
  161. loaded = true;
  162. measureHandler.changeImageLoaded = false;
  163. });
  164. }
  165. } catch (error) {
  166. setState(() {
  167. loaded = true;
  168. measureHandler.changeImageLoaded = false;
  169. });
  170. }
  171. }
  172. }
  173. }
  174. @override
  175. void dispose() {
  176. SystemChrome.setPreferredOrientations([
  177. DeviceOrientation.portraitUp,
  178. ]);
  179. SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
  180. overlays: SystemUiOverlay.values);
  181. SystemChrome.setSystemUIChangeCallback((systemOverlaysAreVisible) async {
  182. // do nothing
  183. });
  184. measureHandler.onChangeImageLoaded.removeListener(changeImage);
  185. measureHandler.changeImageByIndex.removeListener(changeImageByIndex);
  186. super.dispose();
  187. }
  188. @override
  189. FWidget build(BuildContext context) {
  190. FWidget body;
  191. if (!loaded) {
  192. const loadingWidget = FCenter(child: FCircularProgressIndicator());
  193. body = FRow(
  194. children: const [
  195. FExpanded(
  196. child: loadingWidget,
  197. ),
  198. ],
  199. );
  200. } else {
  201. body = FRow(
  202. children: [
  203. FExpanded(
  204. child: FColumn(
  205. mainAxisSize: MainAxisSize.max,
  206. children: [
  207. FExpanded(
  208. child: imageLoaded
  209. ? const FCenter(
  210. child: FCircularProgressIndicator(),
  211. )
  212. : MobileMeasureMainView(
  213. key: ValueKey(
  214. measureData.itemCurrentImage,
  215. ),
  216. isCanWriteReport: widget.isCanWriteReport,
  217. onEditReport: widget.onEditReport,
  218. ),
  219. )
  220. ],
  221. ),
  222. ),
  223. ],
  224. );
  225. }
  226. return FCenter(
  227. child: FContainer(
  228. color: Colors.black,
  229. child: FSafeArea(bottom: false, child: body),
  230. ),
  231. );
  232. }
  233. void _initData() async {
  234. List<RemedicalInfoDTO> remedicals = [];
  235. loaded = false;
  236. var value = await measureData.getRemedicalList.call(
  237. widget.patientCode,
  238. widget.recordCode,
  239. widget.token,
  240. );
  241. for (var remedicalItemList in value) {
  242. remedicals.addAll(remedicalItemList.remedicalList ?? []);
  243. }
  244. /// 获取样式
  245. // _getMeasureSystemSetting();
  246. measureData.remedicalList = remedicals;
  247. var remedicalInfo = await measureData.getImageInfo.call(
  248. _remedicalCode,
  249. widget.token,
  250. widget.remedicalAISelectedInfoCode,
  251. );
  252. if (remedicalInfo != null) {
  253. measureData.aiResults = remedicalInfo.diagnosisResult ?? '';
  254. if (remedicalInfo.terminalImages != null) {
  255. loaded = true;
  256. final imgInfo = remedicalInfo.terminalImages!;
  257. measureData.itemCurrentImage = measureData.chooseImageUrl(imgInfo);
  258. getExamImageInfoList(remedicals);
  259. }
  260. }
  261. measureController.imageLoaded.removeListener(onImageLoaded);
  262. measureController.imageLoaded.addListener(onImageLoaded);
  263. }
  264. void changeImageByIndex(Object sender, RemedicalInfoDTO e) {
  265. _remedicalCode = e.remedicalCode!;
  266. loadLayoutConfig();
  267. getImageInfo();
  268. setState(() {});
  269. }
  270. }