import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:problem_check_system/app/routes/app_routes.dart'; import 'package:problem_check_system/data/models/problem_sync_status.dart'; import 'package:problem_check_system/data/models/problem_model.dart'; import 'package:problem_check_system/modules/problem/views/widgets/custom_button.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; import 'dart:io'; // 添加文件操作支持 // 定义枚举类型 enum ProblemCardViewType { buttons, checkbox } class ProblemCard extends StatelessWidget { final Problem problem; final ProblemCardViewType viewType; final Function(Problem, bool)? onChanged; final bool isSelected; // 改为必需参数 const ProblemCard({ super.key, required this.problem, this.viewType = ProblemCardViewType.buttons, this.onChanged, required this.isSelected, // 改为必需参数 }); @override Widget build(BuildContext context) { // 根据是否已删除决定卡片的颜色 final bool isDeleted = problem.syncStatus == ProblemSyncStatus.pendingDelete; final Color cardColor = isDeleted ? Colors.grey[300]! : Theme.of(context).cardColor; final Color contentColor = isDeleted ? Colors.grey[600]! : Theme.of(context).textTheme.bodyMedium!.color!; return Card( color: cardColor, child: InkWell( onTap: viewType == ProblemCardViewType.checkbox ? () { onChanged?.call(problem, !isSelected); } : null, child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: _buildImageWidget(isDeleted), // 使用新的图片构建方法 title: Text( '问题描述', style: TextStyle(fontSize: 16.sp, color: contentColor), ), subtitle: LayoutBuilder( builder: (context, constraints) { return Text( problem.description, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 14.sp, color: contentColor), ); }, ), ), SizedBox(height: 8.h), Row( children: [ SizedBox(width: 16.w), Icon(Icons.location_on, color: contentColor, size: 16.h), SizedBox(width: 8.w), SizedBox( width: 100.w, child: Text( problem.location, style: TextStyle(fontSize: 12.sp, color: contentColor), overflow: TextOverflow.ellipsis, maxLines: 1, ), ), SizedBox(width: 16.w), Icon(Icons.access_time, color: contentColor, size: 16.h), SizedBox(width: 8.w), Expanded( child: Text( DateFormat( 'yyyy-MM-dd HH:mm:ss', ).format(problem.creationTime), style: TextStyle(fontSize: 12.sp, color: contentColor), ), ), ], ), SizedBox(height: 8.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox(width: 16.w), Wrap( spacing: 8, children: [ ...problem.syncStatus == ProblemSyncStatus.pendingDelete ? [ TDTag( '服务器未删除', isLight: true, theme: TDTagTheme.defaultTheme, textColor: isDeleted ? Colors.grey[700] : null, // backgroundColor: isDeleted // ? Colors.grey[400] // : null, ), ] : [ problem.syncStatus == ProblemSyncStatus.synced ? TDTag( '已上传', isLight: true, theme: TDTagTheme.success, ) : TDTag( '未上传', isLight: true, theme: TDTagTheme.danger, ), problem.bindData != null && problem.bindData!.isNotEmpty ? TDTag( '已绑定', isLight: true, theme: TDTagTheme.primary, ) : TDTag( '未绑定', isLight: true, theme: TDTagTheme.warning, ), ], ], ), const Spacer(), _buildBottomActions(isDeleted), ], ), SizedBox(height: 8.h), ], ), ), ); } Widget _buildImageWidget(bool isDeleted) { return AspectRatio( aspectRatio: 1, // 强制正方形 child: _buildImageContent(isDeleted), ); } Widget _buildImageContent(bool isDeleted) { // 检查是否有图片路径 if (problem.imageUrls.isEmpty || problem.imageUrls[0].localPath.isEmpty) { // 如果没有图片,显示默认占位图 return Image.asset( 'assets/images/problem_preview.png', fit: BoxFit.cover, // 使用 cover 来填充正方形区域 color: isDeleted ? Colors.grey[500] : null, colorBlendMode: isDeleted ? BlendMode.saturation : null, ); } final String imagePath = problem.imageUrls[0].localPath; // 检查文件是否存在 final File imageFile = File(imagePath); if (!imageFile.existsSync()) { // 如果文件不存在,显示默认占位图 return Image.asset( 'assets/images/problem_preview.png', fit: BoxFit.cover, color: isDeleted ? Colors.grey[500] : null, colorBlendMode: isDeleted ? BlendMode.saturation : null, ); } // 如果文件存在,使用 Image.file 加载 return Image.file( imageFile, fit: BoxFit.cover, // 使用 cover 来填充正方形区域 color: isDeleted ? Colors.grey[500] : null, colorBlendMode: isDeleted ? BlendMode.saturation : null, errorBuilder: (context, error, stackTrace) { // 如果加载失败,显示默认图片 return Image.asset( 'assets/images/problem_preview.png', fit: BoxFit.cover, color: isDeleted ? Colors.grey[500] : null, colorBlendMode: isDeleted ? BlendMode.saturation : null, ); }, ); } Widget _buildBottomActions(bool isDeleted) { switch (viewType) { case ProblemCardViewType.buttons: return Row( children: [ if (!isDeleted) CustomButton( text: '修改', onTap: () { Get.toNamed(AppRoutes.problemForm, arguments: problem); }, ), if (!isDeleted) SizedBox(width: 8.w), CustomButton( text: '查看', onTap: () { Get.toNamed( AppRoutes.problemForm, arguments: problem, parameters: {'isReadOnly': 'true'}, ); }, ), SizedBox(width: 16.w), ], ); case ProblemCardViewType.checkbox: return Padding( padding: EdgeInsets.only(right: 16.w), child: Checkbox( value: isSelected, onChanged: (bool? value) { if (value != null) { onChanged?.call(problem, value); } }, ), ); } } }