| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- 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 '../../core/utils/responsive.dart';
- import '../../shared/widgets/form_section.dart';
- import '../../shared/widgets/form_field_row.dart';
- class ExpenseApplicationApplyPage extends ConsumerStatefulWidget {
- final String? id;
- const ExpenseApplicationApplyPage({super.key, this.id});
- @override
- ConsumerState<ExpenseApplicationApplyPage> createState() =>
- _ExpenseApplicationApplyPageState();
- }
- class _ExpenseApplicationApplyPageState
- extends ConsumerState<ExpenseApplicationApplyPage> {
- final _formKey = GlobalKey<FormState>();
- String _expenseType = '差旅费';
- final _amountController = TextEditingController();
- final _purposeController = TextEditingController();
- final _remarkController = TextEditingController();
- static const _types = ['差旅费', '办公用品', '招待费', '交通费', '通讯费', '其他'];
- @override
- void dispose() {
- _amountController.dispose();
- _purposeController.dispose();
- _remarkController.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final r = ResponsiveHelper.of(context);
- return Scaffold(
- appBar: AppBar(title: const Text('报销申请')),
- body: Column(
- children: [
- Expanded(
- child: Center(
- child: ConstrainedBox(
- constraints: BoxConstraints(maxWidth: r.formMaxWidth),
- child: SingleChildScrollView(
- padding: const EdgeInsets.symmetric(vertical: 8),
- child: Form(
- key: _formKey,
- child: _buildForm(),
- ),
- ),
- ),
- ),
- ),
- _buildBottomButtons(),
- ],
- ),
- );
- }
- Widget _buildForm() {
- return FormSection(
- title: '基本信息',
- children: [
- FormFieldRow(
- label: '费用类型',
- value: _expenseType,
- onTap: _showTypePicker,
- ),
- Padding(
- padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
- child: Row(
- children: [
- const SizedBox(
- width: 72,
- child: Text('预计金额',
- style: TextStyle(
- color: AppColors.textSecondary, fontSize: 13)),
- ),
- const SizedBox(width: 8),
- Expanded(
- child: TextFormField(
- controller: _amountController,
- keyboardType:
- const TextInputType.numberWithOptions(decimal: true),
- decoration: const InputDecoration(
- hintText: '请输入金额',
- border: OutlineInputBorder(),
- contentPadding:
- EdgeInsets.symmetric(horizontal: 10, vertical: 8),
- isDense: true,
- ),
- validator: (value) {
- if (value == null || value.isEmpty) {
- return '请输入预计金额';
- }
- if (double.tryParse(value) == null) {
- return '请输入有效数字';
- }
- return null;
- },
- ),
- ),
- ],
- ),
- ),
- Padding(
- padding: const EdgeInsets.fromLTRB(14, 0, 14, 12),
- child: Row(
- children: [
- const SizedBox(
- width: 72,
- child: Text('用途说明',
- style: TextStyle(
- color: AppColors.textSecondary, fontSize: 13)),
- ),
- const SizedBox(width: 8),
- Expanded(
- child: TextFormField(
- controller: _purposeController,
- maxLines: 2,
- decoration: const InputDecoration(
- hintText: '请输入用途说明',
- border: OutlineInputBorder(),
- contentPadding:
- EdgeInsets.symmetric(horizontal: 10, vertical: 8),
- isDense: true,
- ),
- validator: (value) {
- if (value == null || value.isEmpty) {
- return '请输入用途说明';
- }
- return null;
- },
- ),
- ),
- ],
- ),
- ),
- FormFieldRow(
- label: '备注',
- value: _remarkController.text.isEmpty ? null : _remarkController.text,
- hint: '选填',
- onTap: _showRemarkEditor,
- ),
- ],
- );
- }
- Widget _buildBottomButtons() {
- return Container(
- padding: const EdgeInsets.all(12),
- decoration: BoxDecoration(
- color: Colors.white,
- boxShadow: [
- BoxShadow(
- color: Colors.black.withValues(alpha: 0.05),
- blurRadius: 4,
- offset: const Offset(0, -1),
- ),
- ],
- ),
- child: Row(
- children: [
- Expanded(
- child: OutlinedButton(
- onPressed: _handleSaveDraft,
- child: const Text('存草稿'),
- ),
- ),
- const SizedBox(width: 12),
- Expanded(
- flex: 2,
- child: ElevatedButton(
- onPressed: _handleSubmit,
- child: const Text('提交申请'),
- ),
- ),
- ],
- ),
- );
- }
- void _showTypePicker() {
- showModalBottomSheet(
- context: context,
- builder: (_) => Column(
- mainAxisSize: MainAxisSize.min,
- children: _types
- .map((t) => ListTile(
- title: Text(t),
- onTap: () {
- setState(() => _expenseType = t);
- Navigator.pop(context);
- },
- ))
- .toList(),
- ),
- );
- }
- void _showRemarkEditor() {
- showDialog(
- context: context,
- builder: (_) => AlertDialog(
- title: const Text('备注'),
- content: TextField(
- controller: _remarkController,
- maxLines: 3,
- decoration: const InputDecoration(
- hintText: '请输入备注信息…', border: OutlineInputBorder()),
- ),
- actions: [
- TextButton(
- onPressed: () => Navigator.pop(context),
- child: const Text('取消')),
- TextButton(
- onPressed: () {
- setState(() {});
- Navigator.pop(context);
- },
- child: const Text('确定'),
- ),
- ],
- ),
- );
- }
- void _handleSaveDraft() {
- if (!_formKey.currentState!.validate()) return;
- ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(content: Text('草稿已保存')),
- );
- context.pop();
- }
- void _handleSubmit() {
- if (!_formKey.currentState!.validate()) return;
- ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(content: Text('提交成功')),
- );
- context.pop();
- }
- }
|