import 'package:chicken_farm/components/vb_app_bar.dart'; import 'package:chicken_farm/core/config/default_dicts.dart'; import 'package:chicken_farm/modes/system/dict.dart'; import 'package:chicken_farm/stores/dict_stroe.dart'; import 'package:flutter/material.dart'; class DictManagePage extends StatefulWidget { const DictManagePage({super.key}); @override State createState() => _DictManagePageState(); } class _DictManagePageState extends State { final DictStore _dictStore = DictStore(); late Future>> _dictsFuture; final Set _expandedTypes = {}; @override void initState() { super.initState(); _loadDicts(); } void _loadDicts() { setState(() { _dictsFuture = _dictStore.getAllOfflineDicts(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: VberAppBar(title: '字典维护'), body: FutureBuilder>>( future: _dictsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } final dicts = snapshot.data ?? {}; if (dicts.isEmpty) { return const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.info, size: 48, color: Colors.grey), SizedBox(height: 16), Text('暂无字典数据', style: TextStyle(fontSize: 16)), ], ), ); } return ListView.builder( itemCount: dicts.length, itemBuilder: (context, index) { final dictType = dicts.keys.elementAt(index); final dictItems = dicts[dictType] ?? []; final dictName = DefaultDicts.getDictName(dictType); return Card( margin: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0), child: Theme( data: Theme.of( context, ).copyWith(dividerColor: Colors.transparent), child: ExpansionTile( key: Key(dictType), initiallyExpanded: _expandedTypes.contains(dictType), onExpansionChanged: (expanded) { setState(() { if (expanded) { _expandedTypes.add(dictType); } else { _expandedTypes.remove(dictType); } }); }, title: Text('$dictName (${dictItems.length})'), children: [ if (dictItems.isEmpty) const ListTile(title: Text('该类型下暂无数据')) else ...dictItems.map( (item) => ListTile( title: Text(item.dictLabel), subtitle: Text('值: ${item.dictValue}'), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.edit, size: 18), onPressed: () => _editDictItem(dictType, item), ), IconButton( icon: const Icon(Icons.delete, size: 18), onPressed: () => _deleteDictItem(dictType, item), ), ], ), ), ), ListTile( leading: const Icon(Icons.add, color: Colors.blue), title: const Text('添加新项目'), onTap: () => _addNewDictItem(dictType), ), ], ), ), ); }, ); }, ), ); } void _addNewDictItem(String dictType) async { final labelController = TextEditingController(); final valueController = TextEditingController(); final sortController = TextEditingController(text: '0'); final result = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('添加字典项'), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: labelController, decoration: const InputDecoration(labelText: '标签'), ), TextField( controller: valueController, decoration: const InputDecoration(labelText: '值'), ), TextField( controller: sortController, decoration: const InputDecoration(labelText: '排序'), keyboardType: TextInputType.number, ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('确定'), ), ], ), ); if (result == true) { final dictItems = (await _dictStore.getDictByType(dictType)) ?? []; // 生成唯一的dictCode int maxCode = 0; for (final item in dictItems) { if (item.dictCode > maxCode) { maxCode = item.dictCode; } } final newItem = DictDataModel( dictCode: maxCode + 1, dictSort: int.tryParse(sortController.text) ?? 0, dictLabel: labelController.text, dictValue: valueController.text, dictType: dictType, ); try { await _dictStore.addDictItem(dictType, newItem); _loadDicts(); // 重新加载数据 } catch (e) { if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('操作失败: $e'))); } } } } void _editDictItem(String dictType, DictDataModel item) async { final labelController = TextEditingController(text: item.dictLabel); final valueController = TextEditingController(text: item.dictValue); final sortController = TextEditingController( text: item.dictSort.toString(), ); final result = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('编辑字典项'), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: labelController, decoration: const InputDecoration(labelText: '标签'), ), TextField( controller: valueController, decoration: const InputDecoration(labelText: '值'), ), TextField( controller: sortController, decoration: const InputDecoration(labelText: '排序'), keyboardType: TextInputType.number, ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('确定'), ), ], ), ); if (result == true) { final updatedItem = DictDataModel( dictCode: item.dictCode, dictSort: int.tryParse(sortController.text) ?? item.dictSort, dictLabel: labelController.text, dictValue: valueController.text, dictType: dictType, ); try { await _dictStore.updateDictItem(dictType, updatedItem); _loadDicts(); // 重新加载数据 } catch (e) { if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('操作失败: $e'))); } } } } void _deleteDictItem(String dictType, DictDataModel item) async { final confirm = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('确认删除'), content: Text('确定要删除 "${item.dictLabel}" 吗?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('确定'), ), ], ), ); if (confirm == true) { try { await _dictStore.removeDictItem(dictType, item.dictCode); _loadDicts(); // 重新加载数据 } catch (e) { if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('删除失败: $e'))); } } } } }