| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import '../../../core/l10n/app_localizations.dart';
- import '../../../core/navigation/broker_navigation.dart';
- import '../../../core/theme/app_colors.dart';
- import '../../../data/repositories/broker_repository.dart';
- import '../../widgets/common/app_refresh_indicator.dart';
- final _applyListProvider =
- FutureProvider.autoDispose<List<Map<String, dynamic>>>((ref) async {
- final repo = ref.read(brokerRepositoryProvider);
- return repo.getMyApplyList();
- });
- class BrokerApplyScreen extends ConsumerWidget {
- const BrokerApplyScreen({super.key});
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final l10n = AppLocalizations.of(context)!;
- final cs = Theme.of(context).colorScheme;
- final isDark = Theme.of(context).brightness == Brightness.dark;
- final listAsync = ref.watch(_applyListProvider);
- Future<void> refreshList() async {
- ref.invalidate(_applyListProvider);
- await ref.read(_applyListProvider.future);
- }
- return Scaffold(
- appBar: AppBar(
- title: Text(
- l10n.brokerApplyRecords,
- style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
- ),
- centerTitle: true,
- ),
- body: listAsync.when(
- loading: () => const Center(child: CircularProgressIndicator()),
- error: (_, __) => AppRefreshIndicator(
- onRefresh: refreshList,
- child: SingleChildScrollView(
- physics: const AlwaysScrollableScrollPhysics(),
- child: SizedBox(
- height: MediaQuery.sizeOf(context).height * 0.6,
- child: Center(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- Text(l10n.loadFailed,
- style: TextStyle(color: cs.onSurface.withAlpha(153))),
- const SizedBox(height: 12),
- ElevatedButton(
- onPressed: refreshList,
- child: Text(l10n.retry),
- ),
- ],
- ),
- ),
- ),
- ),
- ),
- data: (list) {
- if (list.isEmpty) {
- return AppRefreshIndicator(
- onRefresh: refreshList,
- child: SingleChildScrollView(
- physics: const AlwaysScrollableScrollPhysics(),
- child: SizedBox(
- height: MediaQuery.sizeOf(context).height * 0.6,
- child: _EmptyState(
- l10n: l10n,
- cs: cs,
- isDark: isDark,
- onApply: () => showBrokerApplyDialog(context, ref).then((_) {
- ref.invalidate(_applyListProvider);
- }),
- ),
- ),
- ),
- );
- }
- return AppRefreshIndicator(
- onRefresh: refreshList,
- child: ListView.separated(
- physics: const AlwaysScrollableScrollPhysics(),
- padding: const EdgeInsets.all(16),
- itemCount: list.length,
- separatorBuilder: (_, __) => const SizedBox(height: 12),
- itemBuilder: (_, i) => _ApplyCard(
- item: list[i],
- l10n: l10n,
- cs: cs,
- isDark: isDark,
- ),
- ),
- );
- },
- ),
- );
- }
- }
- class _EmptyState extends StatelessWidget {
- const _EmptyState({
- required this.l10n,
- required this.cs,
- required this.isDark,
- required this.onApply,
- });
- final AppLocalizations l10n;
- final ColorScheme cs;
- final bool isDark;
- final VoidCallback onApply;
- @override
- Widget build(BuildContext context) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.all(32),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.inbox_outlined,
- size: 64, color: cs.onSurface.withAlpha(60)),
- const SizedBox(height: 16),
- Text(l10n.noRecord,
- style: TextStyle(
- color: cs.onSurface.withAlpha(153), fontSize: 15)),
- const SizedBox(height: 24),
- SizedBox(
- width: double.infinity,
- child: ElevatedButton(
- onPressed: onApply,
- style: ElevatedButton.styleFrom(
- backgroundColor: AppColors.brand,
- foregroundColor: Colors.black,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
- ),
- padding: const EdgeInsets.symmetric(vertical: 14),
- ),
- child: Text(
- l10n.applyNow,
- style: const TextStyle(
- fontSize: 15,
- fontWeight: FontWeight.w600,
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
- class _ApplyCard extends StatelessWidget {
- const _ApplyCard(
- {required this.item,
- required this.l10n,
- required this.cs,
- required this.isDark});
- final Map<String, dynamic> item;
- final AppLocalizations l10n;
- final ColorScheme cs;
- final bool isDark;
- @override
- Widget build(BuildContext context) {
- final status = item['auditStatus'];
- // 0=待审核, 1=审核失败, 2=审核通过
- final isPending = isBrokerApplyPending(status);
- final isApproved = status == 2 || status == 'AUDIT_SUCCESS';
- final isRejected = status == 1 || status == 'AUDIT_DEFEATED';
- final statusText = isApproved
- ? l10n.auditStatusApproved
- : isPending
- ? l10n.auditStatusPending
- : l10n.auditStatusRejected;
- final statusColor = isApproved
- ? AppColors.rise
- : isPending
- ? AppColors.brand
- : cs.error;
- final statusBg = isApproved
- ? AppColors.rise.withAlpha(25)
- : isPending
- ? AppColors.brand.withAlpha(25)
- : cs.error.withAlpha(25);
- final createTime = item['createTime']?.toString() ?? '';
- final rejectReason = item['rejectReason']?.toString() ?? '';
- return Container(
- padding: const EdgeInsets.all(16),
- decoration: BoxDecoration(
- color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
- borderRadius: BorderRadius.circular(12),
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- Expanded(
- child: Text(
- l10n.brokerApplyTitle,
- style: TextStyle(
- color: cs.onSurface,
- fontSize: 15,
- fontWeight: FontWeight.w600),
- ),
- ),
- Container(
- padding:
- const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
- decoration: BoxDecoration(
- color: statusBg,
- borderRadius: BorderRadius.circular(12),
- ),
- child: Text(
- statusText,
- style: TextStyle(
- color: statusColor,
- fontSize: 12,
- fontWeight: FontWeight.w600),
- ),
- ),
- ],
- ),
- if (createTime.isNotEmpty) ...[
- const SizedBox(height: 8),
- Text('${l10n.applyTime}: $createTime',
- style:
- TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 13)),
- ],
- if (isRejected && rejectReason.isNotEmpty) ...[
- const SizedBox(height: 8),
- Text('${l10n.rejectReasonLabel}: $rejectReason',
- style: TextStyle(color: cs.error, fontSize: 13)),
- ],
- ],
- ),
- );
- }
- }
|