import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:vitalapp/architecture/utils/advance_debounce.dart'; import 'package:vitalapp/components/no_data_view.dart'; import 'package:vitalapp/database/entities/defines.dart'; import 'package:vitalapp/database/entities/patient.dart'; import '../controller.dart'; import '../state.dart'; enum _SyncCategoryEnum { patient, diagnosis, exam, gxyFollowUp, tnbFollowUp, tcmConsitution, } class _TableUtils { static Map columnWidths = { 0: const FixedColumnWidth(100), 1: const FixedColumnWidth(200), 2: const FixedColumnWidth(250), 3: const FixedColumnWidth(100), 4: const FlexColumnWidth(), 5: const FixedColumnWidth(100), }; /// 行高 static const double rowHeight = 48; /// 字号 static const double textFontSize = 18; } class SyncDataTableHeader extends GetView { const SyncDataTableHeader({super.key}); @override Widget build(BuildContext context) { return Table( columnWidths: _TableUtils.columnWidths, children: [ TableRow( decoration: BoxDecoration( color: Theme.of(context).primaryColor, ), children: const [ SyncTableTextCell(text: "序号", isBlod: true), SyncTableTextCell(text: "姓名", isBlod: true), SyncTableTextCell(text: "身份证号", isBlod: true), SyncTableTextCell(text: "状态", isBlod: true), SyncTableTextCell(text: "待上传项目", isBlod: true), SyncTableTextCell(text: "操作", isBlod: true), ], ), ], ); } } class SyncDataTableBody extends GetView { const SyncDataTableBody({super.key}); @override Widget build(BuildContext context) { final scrollController = ScrollController(); scrollController.addListener( () { // 如果滑动到底部 try { if (scrollController.position.atEdge) { if (scrollController.position.pixels != 0) { if (controller.state.hasNextPage) { controller.loadNextPageList(); } } } } catch (e) { // logger.e("listViewScrollController exception:", e); } }, ); return RefreshIndicator( onRefresh: () async { await controller.reloadPageList(); }, child: Obx(() { final dataList = controller.state.dataList; if (dataList.isEmpty) { return const VNoDataView(); } final List rows = []; for (var i = 0; i < dataList.length; i++) { final model = dataList[i]; rows.add(_buildRow(context, i, model)); } return SingleChildScrollView( controller: scrollController, child: Table( columnWidths: _TableUtils.columnWidths, children: rows, ), ); }), ); } TableRow _buildRow( BuildContext context, int index, SyncCenterDataModel model) { final no = (index + 1).toString(); final data = model.data; return TableRow( key: PageStorageKey(data.code), decoration: BoxDecoration( color: index % 2 == 0 ? null : Colors.blue.shade100, ), children: [ SyncTableTextCell(text: no), SyncTableTextCell(text: data.name), SyncTableTextCell(text: data.code), SyncTableTextCell(text: data.overallSyncState.getDescription()), _buildTagsCell(data), _buildOperateCell(context, index, model), ], ); } /// 操作栏 Widget _buildOperateCell( BuildContext context, int index, SyncCenterDataModel model) { final widgets = []; if (!model.isSynchronized) { widgets.add( TextButton.icon( onPressed: () { Debouncer.run( () { controller.uploadSingle(index); }, ); }, icon: const Icon( Icons.cloud_upload_outlined, size: _TableUtils.textFontSize + 6, ), label: Text( "上传", style: TextStyle( color: Theme.of(context).primaryColor, fontSize: _TableUtils.textFontSize, ), ), ), ); } return _SyncTableCell( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: widgets, ), ); } /// 标签栏 Widget _buildTagsCell(PatientEntity data) { final List tags = []; if (data.syncState != OfflineDataSyncState.success) { tags.add(const _SyncCategoryTag(category: _SyncCategoryEnum.patient)); } if (data.examCount > 0) { tags.add(const _SyncCategoryTag(category: _SyncCategoryEnum.exam)); } if (data.tcmConsitutionCount > 0) { tags.add( const _SyncCategoryTag(category: _SyncCategoryEnum.tcmConsitution)); } if (data.gxyFollowUpCount > 0) { tags.add(const _SyncCategoryTag(category: _SyncCategoryEnum.gxyFollowUp)); } if (data.tnbFollowUpCount > 0) { tags.add(const _SyncCategoryTag(category: _SyncCategoryEnum.tnbFollowUp)); } if (data.diagnosisCount > 0) { tags.add(const _SyncCategoryTag(category: _SyncCategoryEnum.diagnosis)); } return _SyncTableCell( child: Wrap( spacing: 4, runSpacing: 4, children: tags, ), ); } } class SyncTableTextCell extends StatelessWidget { final String? text; final bool isBlod; final AlignmentGeometry? alignment; const SyncTableTextCell({ super.key, this.text, this.isBlod = false, this.alignment, }); @override Widget build(BuildContext context) { final child = Text( text ?? "", style: TextStyle( fontSize: _TableUtils.textFontSize, fontWeight: isBlod ? FontWeight.bold : FontWeight.normal, ), ); return _SyncTableCell( alignment: alignment, child: child, ); } } class _SyncTableCell extends StatelessWidget { final Widget? child; final AlignmentGeometry? alignment; const _SyncTableCell({this.alignment, this.child}); @override Widget build(BuildContext context) { return TableCell( child: Container( alignment: alignment ?? Alignment.center, height: _TableUtils.rowHeight, child: child, ), ); } } class _SyncCategoryTag extends StatelessWidget { static final Map<_SyncCategoryEnum, List> _configMap = { _SyncCategoryEnum.patient: ["档案", Colors.blue], _SyncCategoryEnum.diagnosis: ["检测", Colors.orange], _SyncCategoryEnum.exam: ["检查", Colors.green], _SyncCategoryEnum.gxyFollowUp: ["高血压随访", Colors.purple], _SyncCategoryEnum.tnbFollowUp: ["糖尿病随访", Colors.purple], _SyncCategoryEnum.tcmConsitution: ["中医体质", Colors.brown.shade400], }; final _SyncCategoryEnum category; const _SyncCategoryTag({required this.category}); @override Widget build(BuildContext context) { final configs = _configMap[category]!; final title = configs[0]; final color = configs[1]; return Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: color, ), child: Text( title, style: const TextStyle(color: Colors.white, fontSize: 14), ), ); } }