import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/theme/app_theme.dart'; class SettingsScreen extends ConsumerStatefulWidget { const SettingsScreen({super.key}); @override ConsumerState createState() => _SettingsScreenState(); } class _SettingsScreenState extends ConsumerState { @override Widget build(BuildContext context) { return DefaultTabController( length: 4, child: Column( children: [ Container( color: AppTheme.surface, child: const TabBar( isScrollable: true, labelColor: AppTheme.primary, unselectedLabelColor: AppTheme.textSecondary, indicatorColor: AppTheme.primary, indicatorWeight: 2, labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), tabs: [ Tab(text: '用户管理'), Tab(text: '仓库管理'), Tab(text: '编号规则'), Tab(text: '系统参数'), ], ), ), const Divider(height: 1), Expanded( child: TabBarView( children: [ _buildUsersTab(), _buildWarehousesTab(), _buildNumberRulesTab(), _buildSystemParamsTab(), ], ), ), ], ), ); } Widget _buildUsersTab() { final users = [ {'name': '张三', 'username': 'zhangsan', 'role': '管理员', 'status': true, 'lastLogin': '2026-04-04 09:15'}, {'name': '李四', 'username': 'lisi', 'role': '操作员', 'status': true, 'lastLogin': '2026-04-04 08:30'}, {'name': '王五', 'username': 'wangwu', 'role': '操作员', 'status': true, 'lastLogin': '2026-04-03 17:45'}, {'name': '赵六', 'username': 'zhaoliu', 'role': '只读', 'status': false, 'lastLogin': '2026-03-28 10:20'}, ]; return Column( children: [ Container( height: 52, color: AppTheme.surface, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ ElevatedButton.icon( onPressed: () => _showAddUserDialog(context), icon: const Icon(Icons.person_add, size: 16), label: const Text('新增用户'), ), ], ), ), const Divider(height: 1), Expanded( child: SingleChildScrollView( child: DataTable( headingRowColor: WidgetStateProperty.all(const Color(0xFFF0F4FF)), columns: const [ DataColumn(label: Text('姓名')), DataColumn(label: Text('用户名')), DataColumn(label: Text('角色')), DataColumn(label: Text('状态')), DataColumn(label: Text('最后登录')), DataColumn(label: Text('操作')), ], rows: users .map((u) => DataRow(cells: [ DataCell(Row( mainAxisSize: MainAxisSize.min, children: [ CircleAvatar( radius: 14, backgroundColor: AppTheme.primary.withOpacity(0.15), child: Text( (u['name'] as String).substring(0, 1), style: const TextStyle( fontSize: 12, color: AppTheme.primary, fontWeight: FontWeight.w600), ), ), const SizedBox(width: 8), Text(u['name'] as String), ], )), DataCell(Text(u['username'] as String, style: const TextStyle( fontFamily: 'monospace', fontSize: 12))), DataCell(_RoleBadge(u['role'] as String)), DataCell(Switch( value: u['status'] as bool, onChanged: (_) {}, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, )), DataCell(Text(u['lastLogin'] as String, style: const TextStyle( fontSize: 12, color: AppTheme.textSecondary))), DataCell(Row( mainAxisSize: MainAxisSize.min, children: [ TextButton( onPressed: () {}, child: const Text('编辑', style: TextStyle(fontSize: 12))), TextButton( onPressed: () {}, child: const Text('重置密码', style: TextStyle(fontSize: 12))), ], )), ])) .toList(), ), ), ), ], ); } Widget _buildWarehousesTab() { final warehouses = [ {'code': 'WH001', 'name': '主仓库', 'location': '一楼东侧', 'manager': '张三', 'capacity': 1000, 'used': 680, 'status': true}, {'code': 'WH002', 'name': '副仓库', 'location': '二楼西侧', 'manager': '李四', 'capacity': 500, 'used': 210, 'status': true}, {'code': 'WH003', 'name': '保税仓库', 'location': '地下一层', 'manager': '王五', 'capacity': 300, 'used': 0, 'status': false}, ]; return Column( children: [ Container( height: 52, color: AppTheme.surface, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ ElevatedButton.icon( onPressed: () {}, icon: const Icon(Icons.add, size: 16), label: const Text('新增仓库'), ), ], ), ), const Divider(height: 1), Expanded( child: SingleChildScrollView( child: DataTable( headingRowColor: WidgetStateProperty.all(const Color(0xFFF0F4FF)), columns: const [ DataColumn(label: Text('仓库编号')), DataColumn(label: Text('仓库名称')), DataColumn(label: Text('位置')), DataColumn(label: Text('负责人')), DataColumn(label: Text('使用情况')), DataColumn(label: Text('状态')), DataColumn(label: Text('操作')), ], rows: warehouses .map((w) => DataRow(cells: [ DataCell(Text(w['code'] as String, style: const TextStyle( fontFamily: 'monospace', fontSize: 12))), DataCell(Text(w['name'] as String, style: const TextStyle(fontWeight: FontWeight.w500))), DataCell(Text(w['location'] as String)), DataCell(Text(w['manager'] as String)), DataCell(SizedBox( width: 140, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${w['used']}/${w['capacity']}', style: const TextStyle( fontSize: 12, color: AppTheme.textSecondary), ), const SizedBox(height: 2), LinearProgressIndicator( value: (w['capacity'] as int) > 0 ? (w['used'] as int) / (w['capacity'] as int) : 0, backgroundColor: AppTheme.border, valueColor: AlwaysStoppedAnimation( (w['used'] as int) / (w['capacity'] as int) > 0.8 ? AppTheme.danger : AppTheme.primary, ), ), ], ), )), DataCell(Switch( value: w['status'] as bool, onChanged: (_) {}, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, )), DataCell(Row( mainAxisSize: MainAxisSize.min, children: [ TextButton( onPressed: () {}, child: const Text('编辑', style: TextStyle(fontSize: 12))), ], )), ])) .toList(), ), ), ), ], ); } Widget _buildNumberRulesTab() { final rules = [ {'type': '入库单', 'prefix': 'RK', 'format': 'RK{年}{月}{日}{序号4}', 'example': 'RK20260404001', 'currentNo': 4}, {'type': '出库单', 'prefix': 'CK', 'format': 'CK{年}{月}{日}{序号4}', 'example': 'CK20260404001', 'currentNo': 2}, {'type': '盘点单', 'prefix': 'PD', 'format': 'PD{年}{月}{日}{序号4}', 'example': 'PD20260404001', 'currentNo': 1}, {'type': '商品编码', 'prefix': 'SP', 'format': 'SP{序号3}', 'example': 'SP001', 'currentNo': 12}, ]; return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('编号规则配置', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 4), const Text('配置各类单据的自动编号规则,修改后对新建单据生效', style: TextStyle(fontSize: 13, color: AppTheme.textSecondary)), const SizedBox(height: 16), Card( child: DataTable( headingRowColor: WidgetStateProperty.all(const Color(0xFFF0F4FF)), columns: const [ DataColumn(label: Text('单据类型')), DataColumn(label: Text('前缀')), DataColumn(label: Text('格式')), DataColumn(label: Text('示例')), DataColumn(label: Text('当前序号'), numeric: true), DataColumn(label: Text('操作')), ], rows: rules .map((r) => DataRow(cells: [ DataCell(Text(r['type'] as String, style: const TextStyle(fontWeight: FontWeight.w500))), DataCell(Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( color: AppTheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(3), ), child: Text(r['prefix'] as String, style: const TextStyle( color: AppTheme.primary, fontFamily: 'monospace', fontSize: 13, fontWeight: FontWeight.w600)), )), DataCell(Text(r['format'] as String, style: const TextStyle( fontSize: 12, color: AppTheme.textSecondary))), DataCell(Text(r['example'] as String, style: const TextStyle( fontFamily: 'monospace', fontSize: 12))), DataCell(Text('${r['currentNo']}')), DataCell(TextButton( onPressed: () {}, child: const Text('编辑', style: TextStyle(fontSize: 12)))), ])) .toList(), ), ), ], ), ); } Widget _buildSystemParamsTab() { return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('系统参数', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('基本设置', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryDark)), const Divider(height: 24), _ParamRow(label: '系统名称', value: '酒库管理系统'), _ParamRow(label: '货币单位', value: '人民币(CNY)'), _ParamRow(label: '日期格式', value: 'YYYY-MM-DD'), _ParamRow(label: '时区', value: 'Asia/Shanghai (UTC+8)'), const SizedBox(height: 16), const Text('审核设置', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryDark)), const Divider(height: 24), _ParamRow(label: '入库单需要审核', value: '是', isSwitch: true), _ParamRow(label: '出库单需要审核', value: '是', isSwitch: true), _ParamRow(label: '允许超量出库', value: '否', isSwitch: false), const SizedBox(height: 16), const Text('库存预警设置', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryDark)), const Divider(height: 24), _ParamRow(label: '启用库存预警', value: '是', isSwitch: true), _ParamRow(label: '预警提醒方式', value: '系统内通知'), ], ), ), ), const SizedBox(height: 12), Row( children: [ ElevatedButton( onPressed: () {}, child: const Text('保存设置'), ), const SizedBox(width: 8), OutlinedButton( onPressed: () {}, child: const Text('重置默认'), ), ], ), ], ), ); } void _showAddUserDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('新增用户'), content: SizedBox( width: 400, child: Column( mainAxisSize: MainAxisSize.min, children: [ const TextField( decoration: InputDecoration(labelText: '姓名', hintText: '请输入姓名'), ), const SizedBox(height: 12), const TextField( decoration: InputDecoration(labelText: '用户名', hintText: '请输入登录用户名'), ), const SizedBox(height: 12), const TextField( obscureText: true, decoration: InputDecoration(labelText: '初始密码', hintText: '请设置初始密码'), ), const SizedBox(height: 12), DropdownButtonFormField( value: '操作员', items: ['管理员', '操作员', '只读'] .map((r) => DropdownMenuItem(value: r, child: Text(r))) .toList(), onChanged: (_) {}, decoration: const InputDecoration(labelText: '角色'), ), ], ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () => Navigator.pop(context), child: const Text('确定'), ), ], ), ); } } class _RoleBadge extends StatelessWidget { final String role; const _RoleBadge(this.role); @override Widget build(BuildContext context) { final Color bg; final Color fg; switch (role) { case '管理员': bg = const Color(0xFFE3F2FD); fg = AppTheme.primary; break; case '操作员': bg = const Color(0xFFE8F5E9); fg = AppTheme.success; break; default: bg = const Color(0xFFF5F5F5); fg = AppTheme.textSecondary; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(3)), child: Text(role, style: TextStyle(color: fg, fontSize: 12, fontWeight: FontWeight.w500)), ); } } class _ParamRow extends StatelessWidget { final String label; final String value; final bool? isSwitch; const _ParamRow({required this.label, required this.value, this.isSwitch}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ SizedBox( width: 180, child: Text(label, style: const TextStyle(fontSize: 14, color: AppTheme.textSecondary)), ), if (isSwitch != null) Switch( value: isSwitch!, onChanged: (_) {}, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ) else Text(value, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)), const Spacer(), TextButton(onPressed: () {}, child: const Text('修改', style: TextStyle(fontSize: 12))), ], ), ); } }