|
@@ -4,8 +4,12 @@ import 'package:get/get.dart';
|
|
|
import 'package:vitalapp/architecture/utils/prompt_box.dart';
|
|
|
import 'package:vitalapp/components/appbar.dart';
|
|
|
import 'package:vitalapp/components/search_input.dart';
|
|
|
+import 'package:vitalapp/components/table/table.dart';
|
|
|
+import 'package:vitalapp/components/table/table_column.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/excelData.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/models/excel_data.dart';
|
|
|
+import 'package:vitalapp/pages/widgets/overflow_tooltip_wrapper.dart';
|
|
|
+import 'package:vitalapp/pages/widgets/text_tooltip.dart';
|
|
|
|
|
|
class ExcelDatasView extends StatefulWidget {
|
|
|
final List<ExcelDataRecord> records;
|
|
@@ -23,7 +27,7 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
final _searchController = TextEditingController();
|
|
|
List<ExcelDataRecord> _pendingUploadDatas = [];
|
|
|
List<ExcelDataRecord> _errorDatas = [];
|
|
|
- List<String> _selectedCsvDataCodes = [];
|
|
|
+ List<int> _selecteds = [];
|
|
|
bool _isShowErrorData = false;
|
|
|
bool _isSelectedAll = true;
|
|
|
|
|
@@ -63,8 +67,12 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
if (!_isShowErrorData)
|
|
|
TextButton.icon(
|
|
|
onPressed: () async {
|
|
|
+ List<ExcelDataRecord> pendingUploadDatas = [];
|
|
|
+ for(int i in _selecteds){
|
|
|
+ pendingUploadDatas.add(_pendingUploadDatas[i]);
|
|
|
+ }
|
|
|
var result = await Get.find<IExcelDataManager>()
|
|
|
- .uploadDatas(_pendingUploadDatas, widget.templateKey);
|
|
|
+ .uploadDatas(pendingUploadDatas, widget.templateKey);
|
|
|
if (result) {
|
|
|
PromptBox.toast('上传成功');
|
|
|
Get.back();
|
|
@@ -93,93 +101,21 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
margin: EdgeInsets.symmetric(vertical: 10),
|
|
|
),
|
|
|
Expanded(
|
|
|
- child: ListView(
|
|
|
- children: [
|
|
|
- if (_isShowErrorData) ...[
|
|
|
- ..._errorDatas.map((e) => _buildRecord(e)),
|
|
|
- ] else ...[
|
|
|
- ..._pendingUploadDatas.map((e) => _buildRecord(e)),
|
|
|
- ],
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildRecord(ExcelDataRecord e) {
|
|
|
- List<ExcelDataItem> csvDatas = e.excelDatas;
|
|
|
- List<Widget> children = [];
|
|
|
- for (var c in csvDatas) {
|
|
|
- children.add(_buildItem(c));
|
|
|
- }
|
|
|
- var code = csvDatas
|
|
|
- .firstWhereOrNull((element) => element.key == "sampleBarcode")
|
|
|
- ?.value ??
|
|
|
- '';
|
|
|
- return Container(
|
|
|
- padding: EdgeInsets.only(left: 10),
|
|
|
- width: MediaQuery.of(context).size.width,
|
|
|
- child: Row(
|
|
|
- children: [
|
|
|
- if (!_isShowErrorData)
|
|
|
- Checkbox(
|
|
|
- value: _selectedCsvDataCodes.contains(code),
|
|
|
- onChanged: (v) {
|
|
|
- if (_selectedCsvDataCodes.contains(code)) {
|
|
|
- _selectedCsvDataCodes.remove(code);
|
|
|
- } else {
|
|
|
- _selectedCsvDataCodes.add(code);
|
|
|
- }
|
|
|
- setState(() {});
|
|
|
- },
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: Wrap(
|
|
|
- children: children,
|
|
|
+ child: VitalTable<ExcelDataRecord>(
|
|
|
+ source: _isShowErrorData ? _errorDatas : _pendingUploadDatas,
|
|
|
+ columns: _buildColumns(),
|
|
|
+ headerTextStyle: const TextStyle(
|
|
|
+ fontSize: 12,
|
|
|
),
|
|
|
+ autoHeight: false,
|
|
|
+ showSelect: !_isShowErrorData,
|
|
|
+ onRowSelected: (value, index, selectedIndexs) {
|
|
|
+ _selecteds.add(index);
|
|
|
+ },
|
|
|
+ selecteds: _selecteds,
|
|
|
+ checkCellWidth: 40,
|
|
|
+ cellPadding: EdgeInsets.symmetric(vertical: 2, horizontal: 1),
|
|
|
),
|
|
|
- ],
|
|
|
- ),
|
|
|
- decoration: BoxDecoration(
|
|
|
- border: Border(
|
|
|
- bottom: BorderSide(
|
|
|
- color: Colors.grey[300]!, // 边框颜色
|
|
|
- width: 1.0, // 边框宽度
|
|
|
- ),
|
|
|
- )),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildItem(ExcelDataItem c) {
|
|
|
- if (c.value.isEmpty) {
|
|
|
- return SizedBox();
|
|
|
- }
|
|
|
- String value = c.value;
|
|
|
- if (c.unit.isNotNullOrEmpty) {
|
|
|
- value += " " + c.unit!;
|
|
|
- }
|
|
|
- String title = c.des ?? '';
|
|
|
- if (title.isNotEmpty) {
|
|
|
- title += ":";
|
|
|
- }
|
|
|
- return Row(
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
- children: [
|
|
|
- Text(
|
|
|
- title,
|
|
|
- style: TextStyle(fontWeight: FontWeight.bold),
|
|
|
- ),
|
|
|
- SizedBox(
|
|
|
- width: 3,
|
|
|
- ),
|
|
|
- Text(
|
|
|
- value,
|
|
|
- maxLines: 2,
|
|
|
- style: TextStyle(fontSize: value.length > 40 ? 13 : 14),
|
|
|
- ),
|
|
|
- SizedBox(
|
|
|
- width: 15,
|
|
|
),
|
|
|
],
|
|
|
);
|
|
@@ -189,18 +125,6 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
return Row(
|
|
|
children: [
|
|
|
SizedBox(width: 10),
|
|
|
- if (!_isShowErrorData)
|
|
|
- Checkbox(
|
|
|
- value: _isSelectedAll,
|
|
|
- onChanged: (v) {
|
|
|
- _isSelectedAll = !_isSelectedAll;
|
|
|
- _selectedCsvDataCodes.clear();
|
|
|
- if (_isSelectedAll) {
|
|
|
- _selectedAll();
|
|
|
- }
|
|
|
- setState(() {});
|
|
|
- },
|
|
|
- ),
|
|
|
_buildSearchInput(),
|
|
|
SizedBox(width: 20),
|
|
|
_buildTips(),
|
|
@@ -222,12 +146,10 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
}
|
|
|
|
|
|
void _selectedAll() {
|
|
|
+ int index = 0;
|
|
|
for (var data in _pendingUploadDatas) {
|
|
|
- var code = data.excelDatas
|
|
|
- .firstWhereOrNull((element) => element.key == "sampleBarcode")
|
|
|
- ?.value ??
|
|
|
- '';
|
|
|
- _selectedCsvDataCodes.add(code);
|
|
|
+ _selecteds.add(index);
|
|
|
+ index++;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -278,14 +200,11 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
false)
|
|
|
.toList();
|
|
|
if (_isSelectedAll) {
|
|
|
- _selectedCsvDataCodes.clear();
|
|
|
+ _selecteds.clear();
|
|
|
+ int index = 0;
|
|
|
for (var data in _pendingUploadDatas) {
|
|
|
- var code = data.excelDatas
|
|
|
- .firstWhereOrNull(
|
|
|
- (element) => element.key == "sampleBarcode")
|
|
|
- ?.value ??
|
|
|
- '';
|
|
|
- _selectedCsvDataCodes.add(code);
|
|
|
+ _selecteds.add(index);
|
|
|
+ index++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -316,4 +235,33 @@ class ExcelDatasViewState extends State<ExcelDatasView> {
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ List<TableColumn<ExcelDataRecord>> _buildColumns() {
|
|
|
+ if (widget.records.isEmpty) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ ExcelDataRecord firstRecord = widget.records.first;
|
|
|
+ var items = firstRecord.excelDatas;
|
|
|
+ var textStyle = TextStyle(
|
|
|
+ fontSize: 12,
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
+ fontFamily: "NotoSansSC",
|
|
|
+ );
|
|
|
+ return [
|
|
|
+ ...items.map(
|
|
|
+ (e) => TableColumn<ExcelDataRecord>(
|
|
|
+ headerText: e.des,
|
|
|
+ flex: (e.key == "sampleBarcode" || e.key == "samplingTime") ? 6 : 5,
|
|
|
+ render: (rowData, index) => Center(
|
|
|
+ child: Text(
|
|
|
+ rowData.excelDatas
|
|
|
+ .firstWhere((element) => element.key == e.key)
|
|
|
+ .value,
|
|
|
+ style: textStyle,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|