165 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Dart
		
	
	
import 'dart:io';
 | 
						||
import 'package:flutter/material.dart';
 | 
						||
 | 
						||
Widget HiddenListTable({
 | 
						||
  required List<dynamic> hiddenList,
 | 
						||
  required bool forbidEdit,
 | 
						||
  required String baseImgPath,
 | 
						||
  required String personSignImg,
 | 
						||
  required String personSignTime,
 | 
						||
  required void Function(Map<String, dynamic> item, int index) showHidden,
 | 
						||
  required void Function(Map<String, dynamic> item, int index) removeHidden,
 | 
						||
  required BuildContext context,
 | 
						||
}) {
 | 
						||
  Widget _buildCell(String text, {bool isHeader = false, Alignment alignment = Alignment.center, double minWidth = 40}) {
 | 
						||
    return Container(
 | 
						||
      padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
 | 
						||
      alignment: alignment,
 | 
						||
      child: ConstrainedBox(
 | 
						||
        constraints: BoxConstraints(minWidth: minWidth),
 | 
						||
        child: Text(
 | 
						||
          text,
 | 
						||
          style: TextStyle(
 | 
						||
            fontWeight: isHeader ? FontWeight.bold : FontWeight.normal,
 | 
						||
            fontSize: 14,
 | 
						||
            color: isHeader ? Colors.black87 : Colors.black54,
 | 
						||
          ),
 | 
						||
        ),
 | 
						||
      ),
 | 
						||
    );
 | 
						||
  }
 | 
						||
 | 
						||
  TableRow _buildHeader() {
 | 
						||
    return TableRow(
 | 
						||
      decoration: BoxDecoration(color: Colors.grey.shade200),
 | 
						||
      children: [
 | 
						||
        _buildCell('序号', isHeader: true, alignment: Alignment.center),
 | 
						||
        _buildCell('隐患部位', isHeader: true),
 | 
						||
        _buildCell('隐患描述', isHeader: true),
 | 
						||
        _buildCell('操作', isHeader: true, alignment: Alignment.center),
 | 
						||
      ],
 | 
						||
    );
 | 
						||
  }
 | 
						||
 | 
						||
  TableRow _buildRow(Map<String, dynamic> item, int index) {
 | 
						||
    final partName = (item['HIDDENPART_NAME'] ?? '').toString();
 | 
						||
    final part = (item['HIDDENPART'] ?? '').toString();
 | 
						||
    final descr = (item['HIDDENDESCR'] ?? '').toString();
 | 
						||
 | 
						||
    return TableRow(
 | 
						||
      decoration: BoxDecoration(
 | 
						||
        border: Border(
 | 
						||
          bottom: BorderSide(color: Colors.grey.shade300, width: 0.5),
 | 
						||
        ),
 | 
						||
      ),
 | 
						||
      children: [
 | 
						||
        _buildCell('${index + 1}', alignment: Alignment.center),
 | 
						||
        _buildCell(partName.isNotEmpty ? partName : part),
 | 
						||
        _buildCell(descr),
 | 
						||
        Padding(
 | 
						||
          padding: const EdgeInsets.symmetric(vertical: 6),
 | 
						||
          child: Align(
 | 
						||
            alignment: Alignment.center,
 | 
						||
            child: Row(
 | 
						||
              mainAxisSize: MainAxisSize.min,
 | 
						||
              children: [
 | 
						||
                IconButton(
 | 
						||
                  icon: const Icon(Icons.info_outline, size: 20, color: Colors.blue,),
 | 
						||
                  onPressed: () => showHidden(item, index),
 | 
						||
                  padding: const EdgeInsets.all(4),
 | 
						||
                  constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
 | 
						||
                  visualDensity: VisualDensity.compact,
 | 
						||
                ),
 | 
						||
                if (forbidEdit)
 | 
						||
                  IconButton(
 | 
						||
                    icon: const Icon(Icons.delete_outline, size: 20, color: Colors.red,),
 | 
						||
                    onPressed: () => removeHidden(item, index),
 | 
						||
                    padding: const EdgeInsets.all(4),
 | 
						||
                    constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
 | 
						||
                    visualDensity: VisualDensity.compact,
 | 
						||
                  ),
 | 
						||
              ],
 | 
						||
            ),
 | 
						||
          ),
 | 
						||
        ),
 | 
						||
 | 
						||
      ],
 | 
						||
    );
 | 
						||
  }
 | 
						||
 | 
						||
  Widget _buildHeaderRowWidget() {
 | 
						||
    return Container(
 | 
						||
      decoration: BoxDecoration(color: Colors.grey.shade200),
 | 
						||
      child: Row(
 | 
						||
        children: [
 | 
						||
          Expanded(flex: 1, child: _buildCell('序号', isHeader: true, alignment: Alignment.center)),
 | 
						||
          Expanded(flex: 3, child: _buildCell('隐患部位', isHeader: true)),
 | 
						||
          Expanded(flex: 3, child: _buildCell('隐患描述', isHeader: true)),
 | 
						||
          Expanded(flex: 3, child: _buildCell('操作', isHeader: true, alignment: Alignment.center)),
 | 
						||
        ],
 | 
						||
      ),
 | 
						||
    );
 | 
						||
  }
 | 
						||
 | 
						||
  // 用 LayoutBuilder 安全获取可用宽度(避免直接依赖 MediaQuery.of(context) 的 null 问题)
 | 
						||
  return LayoutBuilder(builder: (ctx, constraints) {
 | 
						||
    // 优先使用父级给出的约束宽度,否则退回到可选的 MediaQuery,再 fallback 一个合理值
 | 
						||
    final double availableWidth = (constraints.maxWidth != double.infinity && constraints.maxWidth > 0)
 | 
						||
        ? constraints.maxWidth
 | 
						||
        : ((MediaQuery.maybeOf(ctx)?.size.width ?? 400.0));
 | 
						||
    final tableWidth = (availableWidth - 20).clamp(200.0, double.infinity);
 | 
						||
 | 
						||
    if (hiddenList.isEmpty) {
 | 
						||
      return SingleChildScrollView(
 | 
						||
        scrollDirection: Axis.horizontal,
 | 
						||
        child: SizedBox(
 | 
						||
          width: tableWidth,
 | 
						||
          child: Column(
 | 
						||
            mainAxisSize: MainAxisSize.min,
 | 
						||
            children: [
 | 
						||
              _buildHeaderRowWidget(),
 | 
						||
              Container(
 | 
						||
                height: 56,
 | 
						||
                decoration: BoxDecoration(
 | 
						||
                  border: Border(
 | 
						||
                    bottom: BorderSide(color: Colors.grey.shade300, width: 0.5),
 | 
						||
                  ),
 | 
						||
                ),
 | 
						||
                alignment: Alignment.center,
 | 
						||
                child: Text(
 | 
						||
                  '暂无数据',
 | 
						||
                  style: TextStyle(fontSize: 14, color: Colors.black54),
 | 
						||
                ),
 | 
						||
              ),
 | 
						||
            ],
 | 
						||
          ),
 | 
						||
        ),
 | 
						||
      );
 | 
						||
    }
 | 
						||
 | 
						||
    return SingleChildScrollView(
 | 
						||
      scrollDirection: Axis.horizontal,
 | 
						||
      child: SizedBox(
 | 
						||
        width: tableWidth,
 | 
						||
        child: Table(
 | 
						||
          defaultVerticalAlignment: TableCellVerticalAlignment.middle,
 | 
						||
          columnWidths: const {
 | 
						||
            0: FlexColumnWidth(1),
 | 
						||
            1: FlexColumnWidth(3),
 | 
						||
            2: FlexColumnWidth(3),
 | 
						||
            3: FlexColumnWidth(3),
 | 
						||
          },
 | 
						||
          border: TableBorder.symmetric(
 | 
						||
            inside: BorderSide(color: Colors.grey.shade300, width: 0.5),
 | 
						||
          ),
 | 
						||
          // 把 map 转成 List<TableRow> 更明确、避免惰性展开可能的问题
 | 
						||
          children: [
 | 
						||
            _buildHeader(),
 | 
						||
            ...hiddenList.asMap().entries.map((e) => _buildRow(e.value, e.key)).toList(),
 | 
						||
          ],
 | 
						||
        ),
 | 
						||
      ),
 | 
						||
    );
 | 
						||
  });
 | 
						||
}
 |