import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:vitalapp/architecture/utils/prompt_box.dart'; import 'package:vitalapp/components/alert_dialog.dart'; import 'package:vitalapp/components/appbar.dart'; import 'package:vitalapp/components/button.dart'; import 'package:vitalapp/components/qr_code_with_logo/qr_code_with_logo.dart'; import 'package:vitalapp/consts/styles.dart'; import 'package:vitalapp/database/entities/defines.dart'; import 'package:vitalapp/pages/check/follow_up/widgets/follow_up_from.dart'; import 'package:vitalapp/pages/check/follow_up_record/controller.dart'; import 'package:vitalapp/pages/check/maternal_health_management/widgets/delete_follow_up_record_button.dart'; import 'package:vitalapp/pages/check/prescription/prescription_form_keys.dart'; import 'package:vitalapp/pages/check/widgets/configurable_card.dart'; import 'package:vitalapp/pages/form/form_info.dart'; import 'package:vitalapp/pages/medical/controller.dart'; import 'package:vitalapp/pages/patient/list/widgets/status.dart'; import 'package:vitalapp/pages/widgets/record_common_item.dart'; class FollowUpRecordPage extends GetView { const FollowUpRecordPage({ Key? key, required this.followUpType, }) : super(key: key); final String followUpType; @override Widget build(BuildContext context) { return GetBuilder( init: FollowUpRecordController( followUpType: followUpType, ), id: "FollowUpRecord", builder: (_) { return Scaffold( backgroundColor: const Color.fromRGBO(238, 238, 238, 1), appBar: VAppBar( titleWidget: Text(controller.getFollowUpValueByKey(followUpType)), actions: [ IconButton( onPressed: () { _changePage(followUpType); }, icon: Icon( Icons.add, size: 48, ), ), SizedBox( width: 8, ) ], ), body: Stack( children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildDiagram(), _buildListView(), ], ) ], ), ); }); } void _changePage(String key) async { FormInfo.instance.formValue.clear(); /// TODO BAKA 急需求 后面改掉 await Get.put(MedicalController()); controller.followUpController.state.followUpTime = DateTime.now(); controller.followUpController.state.nextFollowUpTime = null; controller.followUpController.state.followUpMode = FollowUpModeEnum.Outpatient; controller.followUpController.state.followUpPhoto = ''; await Get.to( ConfigurableCard( cardKey: key, callBack: (key, templateCode, data, prescriptionKey) async { final result = await controller.followUpController.createFollowUp( key, templateCode, data, prescriptionKey.toString(), ); return result; }, followUpWidget: FollowUpFrom( cardKey: key, ), ), transition: Transition.rightToLeft, ); await controller.getFollowUpRecordList(); await Get.find().initRecordDataState(); await Get.delete(); } Widget _buildDiagram() { return Expanded( flex: 1, child: Padding( padding: const EdgeInsets.all(16.0).copyWith(right: 0), child: Container( // color: Colors.white, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, border: Border.all( color: Colors.white, ), borderRadius: GlobalStyles.borderRadius, ), child: Image.asset( 'assets/images/exam/normalMeasurementChart.png', height: double.infinity, fit: BoxFit.fitWidth, ), ), ), ); } Widget _buildListView() { return Expanded( flex: 2, child: Padding( padding: const EdgeInsets.all(16), child: RefreshIndicator( child: Obx( () { final list = controller.state.followUpDTOList; final children = []; for (var i = 0; i < list.length; i++) { final dto = list[i]; final offlineSyncArr = controller.offlineSyncTemp[i]; final records = dto.followUpRecordDatas; if (records == null) { continue; } for (var j = 0; j < records.length; j++) { final data = records[j]; OfflineDataSyncState? offlineSyncState; offlineSyncState = kIsWeb ? null : offlineSyncArr[j]; children.add( _followUpRecordCard( index: j, dto: dto, dataDto: data, syncState: offlineSyncState, ), ); } } return list.isEmpty ? Container( margin: const EdgeInsets.only(top: 80), child: Column( children: [ Center( child: Image.asset( "assets/images/no_data.png", width: 300, height: 300, fit: BoxFit.cover, ), ), const Text( "暂无数据,先看看别的吧", style: TextStyle(fontSize: 18), ), ], ), ) : GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 1, mainAxisSpacing: 16, crossAxisSpacing: 20, childAspectRatio: 900 / 180, ), children: children, ); }, ), onRefresh: () async {}), ), ); } } // ignore: camel_case_types class _followUpRecordCard extends StatelessWidget { final FollowUpRecordDTO dto; final FollowUpRecordDataDTO dataDto; final int index; final OfflineDataSyncState? syncState; // TODO temp _followUpRecordCard({ required this.dto, required this.dataDto, required this.index, this.syncState, }); final controller = Get.find(); @override Widget build(BuildContext context) { final body = Stack( children: [ Row( children: [ Expanded( flex: 10, child: Container( padding: const EdgeInsets.symmetric( horizontal: 30, vertical: 12, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox( height: 8, ), LayoutBuilder(builder: (context, c) { final width = c.maxWidth - 100; return SizedBox( width: width, child: _buildBaseInfoRow(), ); }), const SizedBox( height: 20, ), Wrap( alignment: WrapAlignment.start, spacing: 20, runSpacing: 8, children: [ SizedBox( width: 250, child: RecordCommonItem( itemName: '姓名', itemValue: dto.patientName ?? "", fontSize: 18, ), ), RecordCommonItem( itemName: '随访类型', itemValue: controller.getFollowUpMode(dataDto.followUpMode), fontSize: 18, ), ], ), const SizedBox( height: 20, ), Wrap( alignment: WrapAlignment.start, spacing: 20, runSpacing: 8, children: [ SizedBox( width: 250, child: RecordCommonItem( itemName: '随访医生', itemValue: dataDto.followUpDoctor ?? "", fontSize: 18, ), ), RecordCommonItem( itemName: '随访时间', itemValue: dataDto.followUpTime != null ? DateFormat("yyyy-MM-dd") .format(dataDto.followUpTime!.toLocal()) : "", fontSize: 18, ), ], ) ], ), ), ), // Expanded( // child: IconButton( // onPressed: () { // controller.toCheckPage(dataDto, isCreateFromOldDto: true); // }, // icon: Icon( // Icons.add, // size: 56, // color: Colors.grey.shade400, // ), // ), // ) ], ), Positioned( bottom: 16, right: 160, child: _buildShareButton(), ), Positioned( bottom: 16, right: 40, child: _buildCopyAddButton(dataDto), ), Positioned( top: 16, right: 0, child: _FollowUpRecordSignStatusTag( dataDto: dataDto, ), ), // if(dataDto) Positioned( top: 16, right: 100, child: _OfflineSyncTag(syncState: syncState), ), // Positioned( // bottom: 16, // right: 12, // child: IconButton( // icon: Icon( // Icons.edit, // size: 26, // color: Theme.of(context).primaryColor, // ), // onPressed: () { // controller.toCheckPage(dataDto); //跳转到随访页面 // }, // ), // ), Positioned( bottom: 0, right: 0, child: DeleteFollowUpRecordButton(dataDto.code!, dataDto.key!, () { controller.getFollowUpRecordList(); }), ), ], ); return Material( borderRadius: GlobalStyles.borderRadius, child: Ink( decoration: BoxDecoration( color: Colors.white, borderRadius: GlobalStyles.borderRadius, ), child: InkWell( borderRadius: GlobalStyles.borderRadius, onTap: () { // controller.toFollowUpDetailPage(index, dto); controller.toCheckPage(dataDto); //跳转到随访页面 }, child: body, ), ), ); } Widget _buildBaseInfoRow() { return SizedBox( child: RecordCommonItem( itemName: '随访病症', itemValue: controller.getFollowUpValueByKey(dataDto.key ?? ""), fontSize: 20, ), ); } Widget _buildShareButton() { return Container( width: 120, height: 50, alignment: Alignment.bottomRight, child: VButton( onTap: () async { // 1111 Map preview = await controller.sharePrescription(dataDto); const designWidth = 1280.0; // 设计尺寸宽度:1280 final width = Get.width; final scale = width / designWidth; // 计算缩放比例 if (preview["previewUrl"] == "" || preview["previewUrl"] == null) { PromptBox.toast("暂无处方"); return; } Get.dialog( VAlertDialog( title: "分享处方", width: width * 0.4 / scale, content: _buildQrcode(preview), ), ); }, label: "分享", ), ); } Widget _buildCopyAddButton(FollowUpRecordDataDTO dataDto) { return Container( width: 100, height: 50, alignment: Alignment.bottomRight, child: VButton( onTap: () { controller.toCheckPage(dataDto, isCreateFromOldDto: true); }, label: "复制新增", ), ); } ///二维码 Widget _buildQrcode(Map qr) { return Container( child: VQRCodeWithLogo( qr["previewUrl"], codeStatement: PrescriptionFormKeys.AllFormKeys[qr["key"]] ?? '', operationStatement: "复制链接", size: 200, operationSuccessCallback: () { PromptBox.toast("复制成功"); }, ), ); } } // ignore: camel_case_types class _FollowUpRecordSignStatusTag extends StatelessWidget { final FollowUpRecordDataDTO dataDto; _FollowUpRecordSignStatusTag({required this.dataDto}); final controller = Get.find(); @override Widget build(BuildContext context) { return Container( alignment: Alignment.centerRight, width: 120, child: StatusLabel( title: controller.followUpStateTransition(dataDto.followUpState), color: controller.followUpStateColors(dataDto.followUpState), ), ); } } class _OfflineSyncTag extends StatelessWidget { final OfflineDataSyncState? syncState; const _OfflineSyncTag({required this.syncState}); @override Widget build(BuildContext context) { if (syncState == null || syncState == OfflineDataSyncState.success) { return const SizedBox(); } return Container( height: 30, alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.red, ), child: Text( syncState!.getDescription(), style: const TextStyle(color: Colors.white, fontSize: 14), ), ); } }