import 'package:flutter/material.dart'; import 'package:miaoji_zhang/shared/api/api_client.dart'; import 'package:miaoji_zhang/shared/api/business_api.dart'; import 'package:miaoji_zhang/shared/services/current_ledger_store.dart'; import 'package:miaoji_zhang/shared/services/transaction_events.dart'; import 'package:miaoji_zhang/shared/theme/app_theme.dart'; import 'package:miaoji_zhang/shared/widgets/category_icon.dart'; import 'package:miaoji_zhang/shared/widgets/app_controls.dart'; class RecycleBinPage extends StatefulWidget { const RecycleBinPage({super.key}); @override State createState() => _RecycleBinPageState(); } class _RecycleBinPageState extends State { List _items = const []; bool _loading = true; @override void initState() { super.initState(); _load(); } Future _load() async { setState(() => _loading = true); try { await CurrentLedgerStore.instance.ensureLoaded(); final items = await TxApi.recycleBin(); if (mounted) setState(() => _items = items); } catch (error) { if (mounted) _showError(error); } finally { if (mounted) setState(() => _loading = false); } } Future _restore(TxItem item) async { try { await TxApi.restore(item.id); TransactionEvents.notifyChanged(); await _load(); } catch (error) { if (mounted) _showError(error); } } Future _permanentDelete(TxItem item) async { final confirmed = await _confirm('永久删除', '永久删除后无法恢复,聊天中的账单卡片会显示为已删除。'); if (!confirmed) return; try { await TxApi.permanentlyDelete(item.id); await _load(); } catch (error) { if (mounted) _showError(error); } } Future _clear() async { if (_items.isEmpty) return; final confirmed = await _confirm('清空回收站', '将永久删除当前账本回收站中的全部账单,无法恢复。'); if (!confirmed) return; try { await TxApi.clearRecycleBin(); await _load(); } catch (error) { if (mounted) _showError(error); } } Future _confirm(String title, String message) => showJzConfirmSheet( context, title: title, message: message, confirmLabel: '永久删除', destructive: true, ); Future _showActions(TxItem item) async { final action = await showJzOptionSheet( context, title: item.note ?? item.categoryName, options: const [ JzOption(value: 'restore', label: '恢复账单'), JzOption(value: 'delete', label: '永久删除', subtitle: '删除后无法恢复'), ], ); if (action == 'restore') await _restore(item); if (action == 'delete') await _permanentDelete(item); } void _showError(Object error) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(apiErrorMessage(error)))); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('${CurrentLedgerStore.instance.currentName} · 回收站'), actions: [ TextButton( onPressed: _items.isEmpty ? null : _clear, child: Text('清空'), ), ], ), body: _loading ? Center( child: CircularProgressIndicator( color: AppTheme.primary, strokeWidth: 2, ), ) : _items.isEmpty ? Center( child: Text( '回收站暂无账单\n删除的账单会保留 30 天', textAlign: TextAlign.center, style: TextStyle(color: context.jz.text3, height: 1.6), ), ) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: _items.length, itemBuilder: (context, index) { final item = _items[index]; return Card( child: ListTile( leading: CategoryIconBox( iconKey: item.categoryIcon, colorKey: item.categoryColor, ), title: Text(item.note ?? item.categoryName), subtitle: Text( '${item.occurredAt.year}-${item.occurredAt.month.toString().padLeft(2, '0')}-${item.occurredAt.day.toString().padLeft(2, '0')}', ), trailing: IconButton( tooltip: '账单操作', onPressed: () => _showActions(item), icon: Icon(Icons.more_horiz_rounded), ), ), ); }, ), ); } }