mobile_measure_view.dart 9.5 KB

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