You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
9.9 KiB

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
2 weeks ago
import 'package:problem_check_system/modules/problem/controllers/problem_controller.dart';
import 'package:problem_check_system/data/models/problem_model.dart';
import 'package:problem_check_system/shared/widgets/date_picker_button.dart';
import 'package:problem_check_system/modules/problem/components/problem_card.dart';
import 'package:problem_check_system/modules/problem/views/problem_form_page.dart';
class ProblemPage extends StatelessWidget {
2 weeks ago
const ProblemPage({super.key});
@override
Widget build(BuildContext context) {
2 weeks ago
final ProblemController problemController = Get.find<ProblemController>();
return DefaultTabController(
initialIndex: 0,
length: 2,
child: Scaffold(
body: ConstrainedBox(
constraints: BoxConstraints(maxHeight: 812.h),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 375.w,
height: 83.5.h,
alignment: Alignment.bottomLeft,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft, // 从左开始
end: Alignment.centerRight, // 到右结束
colors: [
Color(0xFF418CFC), // 左侧颜色
Color(0xFF3DBFFC), // 右侧颜色
],
),
),
child: TabBar(
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
color: const Color(0xfffff7f7),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(60),
),
),
tabs: const [
Tab(text: '问题列表'),
Tab(text: '历史问题列表'),
],
labelStyle: TextStyle(
fontFamily: 'MyFont', // 字体名称
fontWeight: FontWeight.w800, // 字重
fontSize: 14.sp, // 字体大小
),
unselectedLabelStyle: TextStyle(
fontFamily: 'MyFont',
fontWeight: FontWeight.w800,
fontSize: 14.sp,
),
labelColor: Colors.black, // 选中文字颜色
unselectedLabelColor: Colors.white, // 未选中文字颜色
),
),
Expanded(
child: TabBarView(
children: [
Column(
children: [
Container(
margin: EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [DatePickerButton(), DatePickerButton()],
),
),
Expanded(
child: Stack(
children: [
Obx(() {
if (problemController.isLoading.value) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: problemController.problems.length,
itemBuilder: (context, index) {
final problem =
problemController.problems[index];
2 weeks ago
return _buildSwipeableProblemCard(
problem,
problemController,
);
},
);
}),
Positioned(
bottom: 5.h,
right: 160.5.w,
child: FloatingActionButton(
heroTag: "123",
onPressed: () {
2 weeks ago
Get.to(() => ProblemFormPage());
},
shape: CircleBorder(),
backgroundColor: Colors.blue[300],
foregroundColor: Colors.white,
child: const Icon(Icons.add),
),
),
],
),
),
],
),
Obx(() {
if (problemController.isLoading.value) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: problemController.problems.length,
itemBuilder: (context, index) {
final problem = problemController.problems[index];
2 weeks ago
return _buildSwipeableProblemCard(
problem,
2 weeks ago
problemController,
viewType: ProblemCardViewType.checkbox,
);
},
);
}),
],
),
),
],
),
),
floatingActionButton: FloatingActionButton(
heroTag: "abc",
onPressed: () {
2 weeks ago
// 批量上传功能
problemController.uploadAllUnuploaded();
},
foregroundColor: Colors.white,
backgroundColor: Colors.red[300],
child: const Icon(Icons.file_upload_outlined),
),
),
);
}
2 weeks ago
// 构建可滑动的ProblemCard组件
Widget _buildSwipeableProblemCard(
Problem problem,
ProblemController controller, {
ProblemCardViewType viewType = ProblemCardViewType.buttons,
}) {
// 使用Dismissible组件实现左滑删除
return Dismissible(
key: Key(problem.id ?? UniqueKey().toString()),
direction: DismissDirection.endToStart, // 只允许从右向左滑动
background: Container(
color: Colors.red,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20.w),
child: Icon(Icons.delete, color: Colors.white, size: 30.sp),
),
confirmDismiss: (direction) async {
// 显示确认对话框
return await _showDeleteConfirmationDialog(problem);
},
onDismissed: (direction) {
// 用户确认后执行删除操作
controller.deleteProblem(problem);
Get.snackbar('成功', '问题已删除');
},
child: ProblemCard(problem, viewType: viewType),
);
}
// 显示删除确认对话框
Future<bool> _showDeleteConfirmationDialog(Problem problem) async {
// 使用 Get.bottomSheet 实现底部确认表单
return await Get.bottomSheet<bool>(
Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 标题
SizedBox(height: 16),
Text(
'确认删除',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
// 内容
Text(
'确定要删除这个问题吗?此操作不可撤销。',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 14, color: Colors.grey[600]),
),
SizedBox(height: 24),
// 删除按钮
ElevatedButton(
onPressed: () => Get.back(result: true),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
padding: EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
'删除',
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
SizedBox(height: 8),
// 取消按钮
TextButton(
onPressed: () => Get.back(result: false),
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 16),
),
child: Text(
'取消',
style: TextStyle(color: Colors.grey[700], fontSize: 16),
),
),
SizedBox(height: 16),
],
),
),
),
isDismissible: false, // 阻止用户点击外部关闭
) ??
false;
}
}