From 4ac7b2a69898f2fcb3283176c36535b40076c271 Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Mon, 10 Nov 2025 16:39:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=97=AA=E7=81=B5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/flisp_page.dart | 21 +++++- lib/pages/todo_page.dart | 2 - lib/utils/flisp_utils.dart | 6 +- lib/widgets/common.dart | 2 +- lib/widgets/flisp_widget.dart | 123 +++++++++++++++++++++++++++++----- 5 files changed, 131 insertions(+), 23 deletions(-) diff --git a/lib/pages/flisp_page.dart b/lib/pages/flisp_page.dart index 264c2f6..ba965a8 100644 --- a/lib/pages/flisp_page.dart +++ b/lib/pages/flisp_page.dart @@ -43,7 +43,7 @@ class FlispPageState extends State { return buildBody( child: Column( children: [ - // 选项卡 + buildStatsCard(_activeFlisps), buildTabs( currentTab: _currentTab, onTabChanged: (value) { @@ -63,10 +63,14 @@ class FlispPageState extends State { return _activeFlisps.isEmpty ? buildEmptyState() : buildFlispList( + context: context, flisps: _activeFlisps, onEdit: (flisp) { _showDialog(true, flisp); }, + onDelete: (flisp) { + _deleteFlisp(flisp); + }, ); } @@ -99,7 +103,6 @@ class FlispPageState extends State { ); } - // 保存待办事项 void _saveFlisp(bool isEditing, Flisp flisp) async { late bool isSuccess; if (isEditing) { @@ -118,4 +121,18 @@ class FlispPageState extends State { showErrorDialog(context, isEditing ? '更新失败' : '添加失败'); } } + + void _deleteFlisp(Flisp flisp) async { + bool isSuccess = await flispService.deleteFlisp(flisp); + + setState(() { + _flisps = flispService.getAllFlisps(); + }); + + if (isSuccess) { + showSuccessDialog(context, '删除成功'); + } else { + showErrorDialog(context, '删除失败'); + } + } } diff --git a/lib/pages/todo_page.dart b/lib/pages/todo_page.dart index 1ae064b..00f2a1e 100644 --- a/lib/pages/todo_page.dart +++ b/lib/pages/todo_page.dart @@ -45,9 +45,7 @@ class TodoPageState extends State { return buildBody( child: Column( children: [ - // 统计信息卡片 buildStatsCard(_todos), - // 选项卡 buildTabs( currentTab: _currentTab, onTabChanged: (value) { diff --git a/lib/utils/flisp_utils.dart b/lib/utils/flisp_utils.dart index 67bd6ab..50e3574 100644 --- a/lib/utils/flisp_utils.dart +++ b/lib/utils/flisp_utils.dart @@ -3,11 +3,11 @@ import 'package:flisp_app/models/flisp.dart'; List getActiveFlisps(FlispTab currentTab, List flisps) { switch (currentTab) { case FlispTab.life: - return flisps.where((flisp) => flisp.tag == FlispTab.life).toList(); + return flisps.where((flisp) => flisp.tag.label == FlispTab.life.label).toList(); case FlispTab.work: - return flisps.where((flisp) => flisp.tag == FlispTab.work).toList(); + return flisps.where((flisp) => flisp.tag.label == FlispTab.work.label).toList(); case FlispTab.study: - return flisps.where((flisp) => flisp.tag == FlispTab.study).toList(); + return flisps.where((flisp) => flisp.tag.label == FlispTab.study.label).toList(); default: return flisps; } diff --git a/lib/widgets/common.dart b/lib/widgets/common.dart index d696bb9..d8e2969 100644 --- a/lib/widgets/common.dart +++ b/lib/widgets/common.dart @@ -20,7 +20,7 @@ Container buildBody({Widget? child}) { Container buildCard({Widget? child}) { return Container( decoration: buildBoxDecoration(), - padding: EdgeInsets.all(16), + padding: EdgeInsets.all(10), child: child, ); } diff --git a/lib/widgets/flisp_widget.dart b/lib/widgets/flisp_widget.dart index b72ae82..c0f4f36 100644 --- a/lib/widgets/flisp_widget.dart +++ b/lib/widgets/flisp_widget.dart @@ -4,6 +4,43 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:toggle_switch/toggle_switch.dart'; +Widget buildStatsCard(List flisps) { + int totalCount = flisps.length; + + int lifeCount = flisps.where((flisp) => flisp.tag == FlispTag.life).length; + int workCount = flisps.where((flisp) => flisp.tag == FlispTag.work).length; + int studyCount = flisps.where((flisp) => flisp.tag == FlispTag.study).length; + + return buildCard( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildStatItem('总计', totalCount, Colors.orange), + _buildStatItem('生活', lifeCount, FlispTag.life.color), + _buildStatItem('工作', workCount, FlispTag.work.color), + _buildStatItem('学习', studyCount, FlispTag.study.color), + ], + ), + ); +} + +Widget _buildStatItem(String label, int count, Color color) { + return Column( + children: [ + Text( + count.toString(), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: color, + ), + ), + const SizedBox(height: 4), + Text(label, style: const TextStyle(fontSize: 12, color: Colors.grey)), + ], + ); +} + Widget buildTabs({ required FlispTab currentTab, required ValueChanged onTabChanged, @@ -32,15 +69,22 @@ Widget buildTabs({ } Widget buildFlispList({ + required BuildContext context, required List flisps, required ValueChanged onEdit, + required ValueChanged onDelete, }) { return ListView.separated( itemCount: flisps.length, separatorBuilder: (context, index) => SizedBox(height: 8), itemBuilder: (context, index) { final flisp = flisps[index]; - return _buildFlispItem(flisp: flisp, onEdit: onEdit); + return _buildFlispItem( + context: context, + flisp: flisp, + onEdit: onEdit, + onDelete: onDelete, + ); }, ); } @@ -180,31 +224,80 @@ Widget _buildFlispSuffix(Flisp flisp) { } Widget _buildFlispItem({ + required BuildContext context, required Flisp flisp, required ValueChanged onEdit, + required ValueChanged onDelete, }) { final hasImage = flisp.imageUrl.isNotEmpty; final hasVideo = flisp.videoUrl.isNotEmpty; - return buildCard( - child: InkWell( - onTap: () => onEdit(flisp), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildFlispContent(flisp), - const SizedBox(height: 8), - if (hasImage) _buildFlispImage(flisp), - const SizedBox(height: 4), - if (hasVideo) _buildFlispVideo(flisp), - const SizedBox(height: 4), - _buildFlispSuffix(flisp), - ], + return Dismissible( + key: ValueKey(flisp.id), + direction: DismissDirection.endToStart, + background: _buildDismissBackground(), + confirmDismiss: (direction) async { + // 这里实现二次确认 + return await _showDeleteConfirmationDialog(context); + }, + onDismissed: (direction) { + onDelete(flisp); + }, + child: Container( + decoration: buildBoxDecoration(), + padding: EdgeInsets.all(16), + child: InkWell( + onTap: () => onEdit(flisp), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildFlispContent(flisp), + const SizedBox(height: 8), + if (hasImage) _buildFlispImage(flisp), + const SizedBox(height: 4), + if (hasVideo) _buildFlispVideo(flisp), + const SizedBox(height: 4), + _buildFlispSuffix(flisp), + ], + ), ), ), ); } +// 确认对话框 +Future _showDeleteConfirmationDialog(BuildContext context) async { + return showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('确认删除'), + backgroundColor: Colors.white, + content: const Text('确定要删除这个项目吗?'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('取消'), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + child: const Text('删除', style: TextStyle(color: Colors.red)), + ), + ], + ); + }, + ); +} + +Widget _buildDismissBackground() { + return Container( + color: Colors.red, + alignment: Alignment.centerRight, + padding: const EdgeInsets.only(right: 20), + child: const Icon(Icons.delete, color: Colors.white, size: 24), + ); +} + // 空状态 Widget buildEmptyState() { return Center(