1.列表,筛选完成和未完成

2.详情,增加checkout
This commit is contained in:
zhutao
2025-09-24 10:22:35 +08:00
parent 9b3c08dabc
commit ca376d9393
19 changed files with 838 additions and 542 deletions

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:plan/page/plan/detail/viewmodel/plan_detail_store.dart';
import 'package:plan/utils/common.dart';
import 'package:plan/utils/format.dart';
import 'package:provider/provider.dart';
class DoneStamp extends StatefulWidget {
@@ -38,6 +40,13 @@ class _DoneStampState extends State<DoneStamp> {
"Completed",
style: TextStyle(fontWeight: FontWeight.w700),
),
Visibility(
visible: getNotEmpty(store.planDetail.planEndTime) != null,
child: Text(
formatDateUS(store.planDetail.planEndTime!),
style: TextStyle(fontSize: 12),
),
),
],
),
),

View File

@@ -5,7 +5,7 @@ import 'package:plan/api/endpoints/plan_api.dart';
import 'package:plan/data/models/plan_acttion_type.dart';
import 'package:plan/page/plan/detail/viewmodel/plan_detail_store.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart';
import 'package:intl/intl.dart';
class FooterBtn extends StatefulWidget {
const FooterBtn({super.key});
@@ -30,6 +30,17 @@ class _FooterBtnState extends State<FooterBtn> {
return item.copyWith(stepStatus: allDone ? 0 : 2);
}).toList();
});
//如果是全部完成
if (!allDone) {
store.updatePlanDetail((dto) {
final now = DateTime.now();
final formatted = DateFormat('yyyy-MM-dd HH:mm:ss').format(now);
print(formatted);
dto.planEndTime = formatted;
});
}
//接口
editPlanStepApi(
store.planId,

View File

@@ -152,80 +152,105 @@ class PlanItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (!isEdit) {
onComplete(step);
}
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
color: Colors.white,
child: DeleteRowItem(
showDelete: isEdit,
onDelete: () {
onDelete(step.id!);
return Selector<PlanDetailStore, String>(
selector: (_, store) => store.planContent,
builder: (context, planContent, _) {
return GestureDetector(
onTap: () {
if (!isEdit && planContent == "") {
onComplete(step);
}
},
builder: (_, animate) {
return [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(bottom: 3),
child: Text(
step.stepContent ?? "",
style: stepTextStyle(context, Theme.of(context).textTheme.bodyMedium),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
color: Colors.white,
child: DeleteRowItem(
showDelete: isEdit,
onDelete: () {
onDelete(step.id!);
},
builder: (_, animate) {
return [
Visibility(
visible: !isEdit && planContent == "",
child: Transform.translate(
offset: Offset(0, -10),
child: Container(
width: 24,
height: 24,
margin: EdgeInsets.only(right: 10),
child: Checkbox(
value: step.stepStatus == 2,
onChanged: (value) {
onComplete(step);
},
),
),
),
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: child,
),
);
},
child: getNotEmpty(step.stepExplain) == null
? SizedBox.shrink(key: ValueKey("empty"))
: Text(
step.stepExplain!,
style: stepTextStyle(
context,
Theme.of(context).textTheme.labelSmall,
),
key: ValueKey(step.stepExplain),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(bottom: 3),
child: Text(
step.stepContent ?? "",
style: stepTextStyle(
context,
Theme.of(context).textTheme.bodyMedium,
),
),
],
),
),
SizeTransition(
axis: Axis.horizontal,
sizeFactor: animate,
child: GestureDetector(
onTap: () {
onEdit(step);
},
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(left: 10),
child: Opacity(
opacity: 0.4,
child: Icon(RemixIcons.edit_box_line),
),
),
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: child,
),
);
},
child: getNotEmpty(step.stepExplain) == null
? SizedBox.shrink(key: ValueKey("empty"))
: Text(
step.stepExplain!,
style: stepTextStyle(
context,
Theme.of(context).textTheme.labelSmall,
),
key: ValueKey(step.stepExplain),
),
),
],
),
),
),
),
];
},
),
),
SizeTransition(
axis: Axis.horizontal,
sizeFactor: animate,
child: GestureDetector(
onTap: () {
onEdit(step);
},
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(left: 10),
child: Opacity(
opacity: 0.4,
child: Icon(RemixIcons.edit_box_line),
),
),
),
),
];
},
),
),
);
},
);
}