import 'package:aioa_mobile/features/assistant/application/leave_progress_controller.dart'; import 'package:aioa_mobile/features/assistant/data/leave_progress_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; class AssistantPage extends ConsumerStatefulWidget { const AssistantPage({super.key}); @override ConsumerState createState() => _AssistantPageState(); } class _AssistantPageState extends ConsumerState { final _controller = TextEditingController(); @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final result = ref.watch(leaveProgressProvider); return Scaffold( appBar: AppBar(title: const Text('AI 流程助手')), body: ListView( padding: const EdgeInsets.all(16), children: [ const Text('询问本人请假流程进度,AI 只读查询,不会执行审批或修改申请。'), const SizedBox(height: 12), TextField( controller: _controller, minLines: 2, maxLines: 4, decoration: const InputDecoration( border: OutlineInputBorder(), hintText: '例如:我最近提交的年假审批到哪一步了?', ), ), const SizedBox(height: 10), FilledButton.icon( onPressed: result.isLoading ? null : () { if (_controller.text.trim().isNotEmpty) { ref .read(leaveProgressProvider.notifier) .ask(_controller.text); } }, icon: const Icon(Icons.auto_awesome), label: const Text('查询进度'), ), const SizedBox(height: 16), result.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Card( child: Padding( padding: const EdgeInsets.all(16), child: Text('查询失败:$e'), ), ), data: (data) => data == null ? const SizedBox.shrink() : _Result( data: data, onSelect: (id) => ref .read(leaveProgressProvider.notifier) .ask('', selectedRequestId: id), ), ), ], ), ); } } class _Result extends StatelessWidget { const _Result({required this.data, required this.onSelect}); final ProgressAnswer data; final ValueChanged onSelect; @override Widget build(BuildContext context) { if (data.requiresSelection) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('找到多条可能的申请,请选择:'), ...data.candidates.map( (c) => Card( child: ListTile( onTap: () => onSelect(c.id), title: Text('${_type(c.type)} · ${_status(c.status)}'), subtitle: Text( '${DateFormat('MM-dd HH:mm').format(c.startsAt.toLocal())} — ${DateFormat('MM-dd HH:mm').format(c.endsAt.toLocal())}', ), trailing: const Icon(Icons.chevron_right), ), ), ), ], ); } final request = data.request!; return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${_type(request.type)} · ${_status(request.status)}', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 10), Text(data.answer ?? ''), if (data.activeTasks.isNotEmpty) ...[ const SizedBox(height: 12), Text('当前节点:${data.activeTasks.join('、')}'), ], if (data.completedTasks.isNotEmpty) Text('已完成:${data.completedTasks.join('、')}'), const SizedBox(height: 12), OutlinedButton.icon( onPressed: () => context.push('/leave/${request.id}'), icon: const Icon(Icons.open_in_new), label: const Text('查看申请详情'), ), ], ), ), ); } static String _type(String v) => {'PERSONAL': '事假', 'SICK': '病假', 'ANNUAL': '年假'}[v] ?? v; static String _status(String v) => { 'DRAFT': '草稿', 'PENDING': '审批中', 'APPROVED': '已通过', 'REJECTED': '已驳回', 'WITHDRAWN': '已撤回', }[v] ?? v; }