3 changed files with 49 additions and 327 deletions
@ -1,285 +0,0 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
import 'package:problem_check_system/app/core/extensions/datetime_extension.dart'; |
||||
import 'package:problem_check_system/app/core/models/sync_status.dart'; |
||||
import 'package:problem_check_system/app/features/enterprise/domain/entities/enterprise_list_item.dart'; |
||||
|
||||
// 主卡片组件 |
||||
class EnterpriseCard extends StatelessWidget { |
||||
final EnterpriseListItem enterpriseListItem; |
||||
final bool isSelected; |
||||
final VoidCallback? onTap; |
||||
final Widget? trailing; |
||||
final Widget? bottomAction; |
||||
|
||||
const EnterpriseCard({ |
||||
super.key, |
||||
required this.enterpriseListItem, |
||||
this.isSelected = false, |
||||
this.onTap, |
||||
this.trailing, |
||||
this.bottomAction, |
||||
}); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return InkWell( |
||||
onTap: onTap, |
||||
child: Container( |
||||
// 【核心修改 1】移除 Container 的 padding |
||||
// padding: EdgeInsets.only(...), // <--- 移除这一段 |
||||
decoration: BoxDecoration( |
||||
color: Colors.white, |
||||
borderRadius: BorderRadius.circular(12.r), |
||||
border: Border.all(color: Colors.grey.shade300, width: 1.w), |
||||
), |
||||
// 【核心修改 2】使用 Clip.antiAlias 来剪裁溢出的按钮部分 |
||||
clipBehavior: Clip.antiAlias, |
||||
child: Stack( |
||||
// Stack 默认会填满父组件(Container) |
||||
children: [ |
||||
// --- 内容层 --- |
||||
// 【核心修改 3】使用 Padding 在 Stack 内部创建内边距 |
||||
Padding( |
||||
padding: EdgeInsets.only( |
||||
left: 16.w, |
||||
right: 16.w, |
||||
top: 16.h, |
||||
// 底部 padding 需要足够大,为按钮留出空间 |
||||
bottom: 0.h, |
||||
), |
||||
child: Column( |
||||
// 让 Column 包裹内容,避免不必要的高度 |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
_buildTopSection(), |
||||
SizedBox(height: 12.h), |
||||
_buildMiddleSection(), |
||||
SizedBox(height: 12.h), |
||||
_buildBottomSection(context), |
||||
], |
||||
), |
||||
), |
||||
|
||||
Positioned( |
||||
bottom: 0, // 相对于卡片底部 |
||||
right: 0, // 相对于卡片右侧 |
||||
child: Row( |
||||
children: [ |
||||
// --- “修改信息” 按钮 --- |
||||
TextButton.icon( |
||||
onPressed: () {}, |
||||
icon: Icon(Icons.edit_outlined, size: 16.sp), |
||||
label: Text('修改信息', style: TextStyle(fontSize: 9.5.sp)), |
||||
style: TextButton.styleFrom( |
||||
foregroundColor: Colors.grey.shade600, |
||||
padding: EdgeInsets.symmetric( |
||||
horizontal: 16.w, |
||||
vertical: 8.h, |
||||
), |
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap, |
||||
minimumSize: const Size(0, 0), |
||||
), |
||||
), |
||||
// --- “查看问题” 按钮 --- |
||||
ElevatedButton( |
||||
onPressed: () {}, |
||||
style: ElevatedButton.styleFrom( |
||||
backgroundColor: const Color(0xFF42A5F5), |
||||
foregroundColor: Colors.white, |
||||
shape: RoundedRectangleBorder( |
||||
borderRadius: BorderRadius.only( |
||||
topLeft: Radius.circular(12.r), |
||||
// 注意:右下角因为贴边,不再需要圆角,否则会有缝隙 |
||||
// bottomRight: Radius.circular(12.r), |
||||
), |
||||
), |
||||
padding: EdgeInsets.symmetric( |
||||
horizontal: 16.w, |
||||
vertical: 8.h, |
||||
), |
||||
// elevation: 0, // 移除阴影,因为它已经被剪裁了 |
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap, |
||||
minimumSize: const Size(0, 0), |
||||
), |
||||
child: Text( |
||||
"查看问题", |
||||
style: TextStyle( |
||||
fontSize: 13.sp, |
||||
fontWeight: FontWeight.w500, |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
|
||||
/// 构建顶部区域:企业名称、类型和状态 |
||||
Widget _buildTopSection() { |
||||
return Row( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
children: [ |
||||
Column( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Text( |
||||
'企业名称', |
||||
style: TextStyle( |
||||
fontSize: 9.sp, |
||||
color: Colors.grey.shade500, |
||||
), // .sp 适配字体 |
||||
), |
||||
SizedBox(height: 4.h), // .h 适配垂直间距 |
||||
Text( |
||||
enterpriseListItem.enterprise.name, |
||||
style: TextStyle( |
||||
fontSize: 12.5.sp, |
||||
fontWeight: FontWeight.w500, |
||||
color: Colors.black87, |
||||
), |
||||
overflow: TextOverflow.ellipsis, |
||||
), |
||||
], |
||||
), |
||||
|
||||
Column( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Text( |
||||
'企业类型', |
||||
style: TextStyle(fontSize: 9.sp, color: Colors.grey.shade500), |
||||
), |
||||
SizedBox(height: 4.h), |
||||
Text( |
||||
enterpriseListItem.enterprise.type, |
||||
style: TextStyle( |
||||
fontSize: 12.5.sp, |
||||
fontWeight: FontWeight.w500, |
||||
color: Colors.black87, |
||||
), |
||||
overflow: TextOverflow.ellipsis, |
||||
), |
||||
], |
||||
), |
||||
// SizedBox(width: 8.w), |
||||
Container( |
||||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 3.h), |
||||
decoration: BoxDecoration( |
||||
borderRadius: BorderRadius.circular(8.r), |
||||
border: Border.all(color: Colors.red.shade400, width: 1.w), |
||||
), |
||||
child: Text( |
||||
enterpriseListItem.enterprise.syncStatus == SyncStatus.synced |
||||
? '信息已上传' |
||||
: '信息未上传', |
||||
style: TextStyle(fontSize: 7.sp, color: Colors.red.shade400), |
||||
), |
||||
), |
||||
], |
||||
); |
||||
} |
||||
|
||||
/// 构建中间区域:问题总数和创建时间 |
||||
Widget _buildMiddleSection() { |
||||
return Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
children: [ |
||||
Row( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Icon(Icons.description_outlined, color: Colors.grey, size: 16.sp), |
||||
SizedBox(width: 4.w), |
||||
Text( |
||||
'问题总数: ', |
||||
style: TextStyle(fontSize: 12.sp, color: Colors.grey), |
||||
), |
||||
Text( |
||||
enterpriseListItem.totalProblems.toString(), |
||||
style: TextStyle( |
||||
fontSize: 12.5.sp, |
||||
color: Colors.black87, |
||||
fontWeight: FontWeight.w500, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
Row( |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
Icon(Icons.access_time, color: Colors.grey, size: 16.sp), |
||||
Text( |
||||
'创建时间: ${enterpriseListItem.enterprise.creationTime.toDateTimeString()}', |
||||
style: TextStyle(fontSize: 12.sp, color: Colors.grey), |
||||
), |
||||
], |
||||
), |
||||
], |
||||
); |
||||
} |
||||
|
||||
/// 构建底部区域:标签和复选框 |
||||
Widget _buildBottomSection(BuildContext context) { |
||||
return Row( |
||||
children: [ |
||||
_buildTag( |
||||
text: '已上传 ${enterpriseListItem.uploadedProblems}', |
||||
textColor: Colors.blue.shade700, |
||||
backgroundColor: Colors.blue.shade50, |
||||
), |
||||
SizedBox(width: 8.w), |
||||
_buildTag( |
||||
text: '未上传 ${enterpriseListItem.pendingProblems}', |
||||
textColor: Colors.red.shade600, |
||||
backgroundColor: Colors.red.shade50, |
||||
), |
||||
const Spacer(), |
||||
// Theme( |
||||
// data: Theme.of(context).copyWith( |
||||
// checkboxTheme: CheckboxThemeData( |
||||
// // 将点击区域收缩,移除额外的 padding |
||||
// materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
||||
// // (可选) 进一步压缩视觉密度 |
||||
// visualDensity: VisualDensity.compact, |
||||
// ), |
||||
// ), |
||||
// child: Checkbox( |
||||
// value: isSelected, |
||||
// onChanged: onSelectionChanged, |
||||
// materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
||||
// visualDensity: VisualDensity.compact, |
||||
// ), |
||||
// ), |
||||
], |
||||
); |
||||
} |
||||
|
||||
/// 用于创建“已上传”和“未上传”标签的辅助方法 |
||||
Widget _buildTag({ |
||||
required String text, |
||||
required Color textColor, |
||||
required Color backgroundColor, |
||||
}) { |
||||
return Container( |
||||
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h), |
||||
decoration: BoxDecoration( |
||||
color: backgroundColor, |
||||
// borderRadius: BorderRadius.circular(4.r), |
||||
// border: Border.all(color: textColor.withAlpha(128), width: 1.w), |
||||
), |
||||
child: Text( |
||||
text, |
||||
style: TextStyle( |
||||
color: textColor, |
||||
fontSize: 10.sp, |
||||
fontWeight: FontWeight.w500, |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue