import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/theme/app_colors.dart'; import '../shell/nav_bar_config.dart'; import '../../core/utils/responsive.dart'; import '../../shared/widgets/action_bar.dart'; import '../../core/i18n/app_localizations.dart'; import '../../shared/widgets/form_section.dart'; class AnnouncementCreatePage extends ConsumerStatefulWidget { const AnnouncementCreatePage({super.key}); @override ConsumerState createState() => _AnnouncementCreatePageState(); } class _AnnouncementCreatePageState extends ConsumerState { final _titleCtrl = TextEditingController(); final _contentCtrl = TextEditingController(); String _type = '通知公告'; String _scope = '全员'; bool _isTop = false; DateTime _expiryDate = DateTime.now().add(const Duration(days: 30)); final _types = ['通知公告', '人事与制度', '放假与活动']; @override void dispose() { _titleCtrl.dispose(); _contentCtrl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final r = ResponsiveHelper.of(context); final l10n = AppLocalizations.of(context); ref .read(navBarConfigProvider.notifier) .update( NavBarConfig( title: l10n.get('announcementCreate'), showBack: true, onBack: () => context.pop(), ), ); return Column( children: [ Expanded( child: Align( alignment: Alignment.topCenter, child: ConstrainedBox( constraints: BoxConstraints(maxWidth: r.formMaxWidth), child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( children: [ // 基本信息 FormSection( title: '基本信息', children: [ // 标题输入 Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 12, ), decoration: BoxDecoration( color: AppColors.bgPage, borderRadius: BorderRadius.circular(4), ), child: TextField( controller: _titleCtrl, decoration: const InputDecoration( hintText: '请输入公告标题', hintStyle: TextStyle( fontSize: 14, color: AppColors.textPlaceholder, ), border: InputBorder.none, contentPadding: EdgeInsets.zero, isDense: true, ), style: const TextStyle( fontSize: 14, color: AppColors.textPrimary, ), ), ), const SizedBox(height: 12), // 公告类型 _buildSelectRow('公告类型', _type, _pickType), ], ), const SizedBox(height: 16), // 公告内容 FormSection( title: '公告内容', children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.bgPage, borderRadius: BorderRadius.circular(4), ), height: 200, child: TextField( controller: _contentCtrl, maxLines: null, expands: true, textAlignVertical: TextAlignVertical.top, decoration: const InputDecoration( hintText: '请输入公告正文内容...', hintStyle: TextStyle( fontSize: 14, color: AppColors.textPlaceholder, ), border: InputBorder.none, contentPadding: EdgeInsets.zero, ), style: const TextStyle( fontSize: 14, color: AppColors.textPrimary, height: 1.7, ), ), ), ], ), const SizedBox(height: 16), // 发布设置 FormSection( title: '发布设置', children: [ // 置顶开关 _buildSwitchRow('置顶公告', _isTop, (v) { setState(() => _isTop = v); }), const Divider(height: 1, color: AppColors.border), // 有效期 _buildSelectRow( '有效期至', '${_expiryDate.year}-${_expiryDate.month.toString().padLeft(2, '0')}-${_expiryDate.day.toString().padLeft(2, '0')}', _pickExpiryDate, ), const Divider(height: 1, color: AppColors.border), // 接收范围 _buildSelectRow('接收范围', _scope, _pickScope), ], ), const SizedBox(height: 16), // 附件 FormSection( title: '附件', children: [ Container( height: 80, decoration: BoxDecoration( color: AppColors.bgPage, borderRadius: BorderRadius.circular(4), ), child: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.add_photo_alternate_outlined, size: 28, color: AppColors.primary, ), SizedBox(height: 4), Text( '添加附件', style: TextStyle( fontSize: 12, color: AppColors.primary, ), ), ], ), ), ), ], ), const SizedBox(height: 80), ], ), ), ), ), ), // ActionBar ActionBar( centerLabel: '存草稿', rightLabel: '发布', showLeft: false, onCenterTap: _saveDraft, onRightTap: _submit, ), ], ); } Widget _buildSelectRow(String label, String value, VoidCallback onTap) { return GestureDetector( onTap: onTap, child: Container( height: 44, alignment: Alignment.centerLeft, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: const TextStyle( fontSize: 14, color: AppColors.textSecondary, ), ), Row( mainAxisSize: MainAxisSize.min, children: [ Text( value, style: const TextStyle( fontSize: 14, color: AppColors.primary, ), ), const SizedBox(width: 4), const Icon( Icons.chevron_right, size: 14, color: AppColors.textPlaceholder, ), ], ), ], ), ), ); } Widget _buildSwitchRow( String label, bool value, ValueChanged onChanged, ) { return Container( height: 44, alignment: Alignment.centerLeft, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: const TextStyle( fontSize: 14, color: AppColors.textSecondary, ), ), Switch( value: value, onChanged: onChanged, activeColor: AppColors.primary, ), ], ), ); } Future _pickType() async { final result = await showDialog( context: context, builder: (ctx) => SimpleDialog( title: const Text('选择公告类型'), children: _types .map( (t) => SimpleDialogOption( onPressed: () => Navigator.pop(ctx, t), child: Text(t), ), ) .toList(), ), ); if (result != null) setState(() => _type = result); } Future _pickExpiryDate() async { final picked = await showDatePicker( context: context, initialDate: _expiryDate, firstDate: DateTime.now(), lastDate: DateTime(2030), ); if (picked != null) setState(() => _expiryDate = picked); } Future _pickScope() async { final result = await showDialog( context: context, builder: (ctx) => SimpleDialog( title: const Text('选择接收范围'), children: ['全员', '部门'] .map( (s) => SimpleDialogOption( onPressed: () => Navigator.pop(ctx, s), child: Text(s), ), ) .toList(), ), ); if (result != null) setState(() => _scope = result); } void _saveDraft() { // TODO: 存草稿逻辑 ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('已保存草稿'))); } Future _submit() async { await Future.delayed(const Duration(milliseconds: 500)); if (context.mounted) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('公告发布成功'))); context.pop(); } } }