Browse Source

feat : 图片删除效果

dev
徐振升 9 hours ago
parent
commit
b614000b77
  1. 7
      lib/data/providers/sqlite_provider.dart
  2. 11
      lib/modules/problem/controllers/problem_controller.dart
  3. 1
      lib/modules/problem/views/problem_page.dart
  4. 8
      lib/modules/problem/views/problem_upload_page.dart
  5. 162
      lib/modules/problem/views/widgets/problem_card.dart

7
lib/data/providers/sqlite_provider.dart

@ -136,14 +136,9 @@ class SQLiteProvider extends GetxService {
///
Future<int> updateProblem(Problem problem) async {
try {
//
final problemToUpdate = problem.copyWith(
syncStatus: SyncStatus.notSynced,
);
final result = await _database.update(
_tableName,
problemToUpdate.toMap(),
problem.toMap(),
where: 'id = ?',
whereArgs: [problem.id],
);

11
lib/modules/problem/controllers/problem_controller.dart

@ -331,7 +331,15 @@ class ProblemController extends GetxController
if (picked != null) {
//
historyStartTime.value = picked.start;
historyEndTime.value = picked.end;
historyEndTime.value = DateTime(
picked.end.year,
picked.end.month,
picked.end.day,
23,
59,
59,
999,
);
loadProblems();
log('选择的日期范围是: ${picked.start}${picked.end}');
}
@ -394,6 +402,7 @@ class ProblemController extends GetxController
///
void showUploadPage() {
Get.toNamed(AppRoutes.problemUpload);
clearSelection();
loadUnUploadedProblems();
}

1
lib/modules/problem/views/problem_page.dart

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:problem_check_system/app/routes/app_routes.dart';
import 'package:problem_check_system/modules/problem/controllers/problem_controller.dart';
import 'package:problem_check_system/modules/problem/views/problem_list_page.dart'; // ProblemListPage
import 'package:problem_check_system/modules/problem/views/widgets/current_filter_bar.dart';

8
lib/modules/problem/views/problem_upload_page.dart

@ -24,7 +24,13 @@ class ProblemUploadPage extends GetView<ProblemController> {
return Text('已选择$selectedCount项');
}),
centerTitle: true,
leading: IconButton(icon: Icon(Icons.close), onPressed: () => Get.back()),
// leading: IconButton(
// icon: Icon(Icons.close),
// onPressed: () {
// Get.back();
// controller.clearSelection();
// },
// ),
actions: [
Obx(
() => TextButton(

162
lib/modules/problem/views/widgets/problem_card.dart

@ -6,8 +6,8 @@ import 'package:problem_check_system/app/routes/app_routes.dart';
import 'package:problem_check_system/data/models/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:problem_check_system/modules/problem/views/problem_form_page.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'dart:io'; //
//
enum ProblemCardViewType { buttons, checkbox }
@ -28,11 +28,20 @@ class ProblemCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
//
final bool isDeleted = problem.isDeleted;
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,
@ -40,18 +49,18 @@ class ProblemCard extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Image.asset(
'assets/images/problem_preview.png',
fit: BoxFit.contain,
leading: _buildImageWidget(isDeleted), // 使
title: Text(
'问题描述',
style: TextStyle(fontSize: 16.sp, color: contentColor),
),
title: Text('问题描述', style: TextStyle(fontSize: 16.sp)),
subtitle: LayoutBuilder(
builder: (context, constraints) {
return Text(
problem.description,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14.sp),
style: TextStyle(fontSize: 14.sp, color: contentColor),
);
},
),
@ -60,27 +69,26 @@ class ProblemCard extends StatelessWidget {
Row(
children: [
SizedBox(width: 16.w),
Icon(Icons.location_on, color: Colors.grey, size: 16.h),
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),
style: TextStyle(fontSize: 12.sp, color: contentColor),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
SizedBox(width: 16.w),
Icon(Icons.access_time, color: Colors.grey, size: 16.h),
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),
// overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12.sp, color: contentColor),
),
),
],
@ -93,20 +101,46 @@ class ProblemCard extends StatelessWidget {
Wrap(
spacing: 8,
children: [
problem.syncStatus == SyncStatus.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,
),
...problem.isDeleted
? [
TDTag(
'已删除',
theme: TDTagTheme.danger,
textColor: isDeleted ? Colors.grey[700] : null,
backgroundColor: isDeleted
? Colors.grey[400]
: null,
),
]
: [
problem.syncStatus == SyncStatus.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(), //
_buildBottomActions(isDeleted),
],
),
SizedBox(height: 8.h),
@ -116,18 +150,70 @@ class ProblemCard extends StatelessWidget {
);
}
Widget _buildBottomActions() {
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: [
CustomButton(
text: '修改',
onTap: () {
Get.toNamed(AppRoutes.problemForm, arguments: problem);
},
),
SizedBox(width: 8.w),
if (!isDeleted)
CustomButton(
text: '修改',
onTap: () {
Get.toNamed(AppRoutes.problemForm, arguments: problem);
},
),
if (!isDeleted) SizedBox(width: 8.w),
CustomButton(
text: '查看',
onTap: () {
@ -145,12 +231,14 @@ class ProblemCard extends StatelessWidget {
return Padding(
padding: EdgeInsets.only(right: 16.w),
child: Checkbox(
value: isSelected, // 使
onChanged: (bool? value) {
if (value != null) {
onChanged?.call(problem, value);
}
},
value: isSelected,
onChanged: isDeleted
? null
: (bool? value) {
if (value != null) {
onChanged?.call(problem, value);
}
},
),
);
}

Loading…
Cancel
Save