| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- import 'package:flutter/material.dart';
- import 'package:tdesign_flutter/tdesign_flutter.dart';
- import '../../core/i18n/app_localizations.dart';
- import '../../core/theme/app_colors_extension.dart';
- /// 单据状态标签 + 底部操作按钮。
- ///
- /// 根据 [billStatus] 中的 `approvalStatus`(SHCOUNT0~6)、
- /// `isClosed`、`isTransferred`、`isCreator`、`canEdit` 控制展示。
- ///
- /// 使用方式:
- /// ```dart
- /// BillStatusBar(
- /// billStatus: _billStatus,
- /// onEdit: () => context.push('/xxx/edit/$billNo'),
- /// onSubmit: () => api.shSubmit(bilNo: billNo, bilDd: ...),
- /// onCancelSubmit: () => api.shSubmit(bilNo: billNo, bilDd: ..., isCancel: true),
- /// onTapStatusTag: () => _showAuditTrail(),
- /// ),
- /// ```
- class BillStatusBar {
- /// getBillStatus 接口返回的完整 Map,为 null 时显示空状态。
- final Map<String, dynamic>? billStatus;
- /// "修改"按钮回调
- final VoidCallback? onEdit;
- /// "提交"按钮回调(shSubmit)
- final VoidCallback? onSubmit;
- /// "取消提交"按钮回调(shSubmit + isCancel)
- final VoidCallback? onCancelSubmit;
- /// "还车"按钮回调(仅用车申请单使用)
- final VoidCallback? onReturn;
- /// 点击状态标签回调(查看审批轨迹)
- final VoidCallback? onTapStatusTag;
- /// 已关闭状态文本(如"已关闭",仅 expense 使用)
- final String? closedText;
- /// 已转单状态文本(如"已转为报销单",expense/expense_apply 使用)
- final String? transferredText;
- const BillStatusBar({
- this.billStatus,
- this.onEdit,
- this.onSubmit,
- this.onCancelSubmit,
- this.onReturn,
- this.onTapStatusTag,
- this.closedText,
- this.transferredText,
- });
- // ── 派生状态 ──
- bool get _isClosed => billStatus?['isClosed'] == true;
- bool get _isTransferred => billStatus?['isTransferred'] == true;
- String? get _approvalStatus => billStatus?['approvalStatus'] as String?;
- String? get _approvalText => billStatus?['approvalText'] as String?;
- bool get _canEdit => billStatus?['canEdit'] == true;
- // ── 按钮显隐 ──
- bool get showEdit {
- final s = _approvalStatus;
- if (s == 'SHCOUNT0' || s == 'SHCOUNT3') return _canEdit;
- if (s == 'SHCOUNT6') return _canEdit;
- return false;
- }
- bool get showSubmit {
- final s = _approvalStatus;
- return s == 'SHCOUNT0' || s == 'SHCOUNT3';
- }
- bool get showCancelSubmit => _approvalStatus == 'SHCOUNT1';
- bool get showReturn {
- if (onReturn == null) return false;
- final s = _approvalStatus;
- return (s == 'SHCOUNT4' || s == 'SHCOUNT6') && !_isClosed && !_isTransferred;
- }
- bool get _showButtons => showEdit || showSubmit || showCancelSubmit || showReturn;
- // ── 状态标签数据 ──
- ({IconData icon, Color color}) _statusStyle() {
- if (_isClosed) {
- return (icon: Icons.lock_outline, color: Colors.blueGrey);
- }
- if (_isTransferred) {
- return (icon: Icons.swap_horiz, color: Colors.blue);
- }
- final s = _approvalStatus;
- if (s == null || s.isEmpty) {
- return (icon: Icons.help_outline, color: Colors.grey);
- }
- switch (s) {
- case 'SHCOUNT0':
- return (icon: Icons.edit_note, color: Colors.teal);
- case 'SHCOUNT1':
- return (icon: Icons.hourglass_empty, color: Colors.orange);
- case 'SHCOUNT2':
- return (icon: Icons.cancel_outlined, color: Colors.red);
- case 'SHCOUNT3':
- return (icon: Icons.undo, color: Colors.deepOrange);
- case 'SHCOUNT4':
- return (icon: Icons.check_circle_outline, color: Colors.green);
- case 'SHCOUNT5':
- return (icon: Icons.sync, color: Colors.blue);
- case 'SHCOUNT6':
- return (icon: Icons.verified, color: Colors.indigo);
- default:
- return (icon: Icons.help_outline, color: Colors.grey);
- }
- }
- String? get _displayText {
- if (_isClosed) return closedText;
- if (_isTransferred) return transferredText;
- return _approvalText;
- }
- // ── 构建 ──
- /// 仅状态标签(用于 FormSection trailing)
- Widget buildStatusTag(BuildContext context) {
- final style = _statusStyle();
- final text = _displayText;
- if (text == null || text.isEmpty) return const SizedBox.shrink();
- final tag = Container(
- padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
- decoration: BoxDecoration(
- color: style.color.withValues(alpha: 0.1),
- borderRadius: BorderRadius.circular(6),
- border: Border.all(
- color: style.color.withValues(alpha: 0.3),
- width: 0.5,
- ),
- ),
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(style.icon, size: 18, color: style.color),
- const SizedBox(width: 4),
- Text(
- text,
- style: TextStyle(
- fontSize: 13,
- fontWeight: FontWeight.w600,
- color: style.color,
- ),
- ),
- ],
- ),
- );
- if (onTapStatusTag != null) {
- return GestureDetector(onTap: onTapStatusTag, child: tag);
- }
- return tag;
- }
- /// 底部操作按钮区
- Widget buildActions(BuildContext context) {
- if (!_showButtons) return const SizedBox.shrink();
- final colors = Theme.of(context).extension<AppColorsExtension>()!;
- final l10n = AppLocalizations.of(context);
- final bottomPadding = MediaQuery.of(context).padding.bottom;
- return Container(
- padding: EdgeInsets.fromLTRB(16, 12, 16, 12 + bottomPadding),
- decoration: BoxDecoration(
- color: colors.bgCard,
- border: Border(top: BorderSide(color: colors.border)),
- ),
- child: Row(
- children: [
- if (showEdit) ...[
- Expanded(
- child: TDButton(
- icon: TDIcons.edit,
- text: _editLabel(l10n),
- size: TDButtonSize.medium,
- type: TDButtonType.outline,
- shape: TDButtonShape.round,
- theme: TDButtonTheme.primary,
- onTap: onEdit,
- ),
- ),
- ],
- if (showEdit && (showSubmit || showCancelSubmit))
- const SizedBox(width: 12),
- if (showSubmit)
- Expanded(
- child: TDButton(
- icon: TDIcons.send,
- text: _submitLabel(l10n),
- size: TDButtonSize.medium,
- type: TDButtonType.fill,
- shape: TDButtonShape.round,
- theme: TDButtonTheme.primary,
- onTap: onSubmit,
- ),
- ),
- if (showCancelSubmit)
- Expanded(
- child: TDButton(
- icon: TDIcons.rollback,
- text: _cancelSubmitLabel(l10n),
- size: TDButtonSize.medium,
- type: TDButtonType.fill,
- shape: TDButtonShape.round,
- theme: TDButtonTheme.danger,
- onTap: onCancelSubmit,
- ),
- ),
- if (showReturn) ...[
- if (showEdit || showSubmit || showCancelSubmit)
- const SizedBox(width: 12),
- Expanded(
- child: TDButton(
- icon: Icons.directions_car,
- text: _returnLabel(l10n),
- size: TDButtonSize.medium,
- type: TDButtonType.fill,
- shape: TDButtonShape.round,
- theme: TDButtonTheme.primary,
- onTap: onReturn,
- ),
- ),
- ],
- ],
- ),
- );
- }
- // ── 按钮标签 ──
- /// 默认返回中文按钮标签(不依赖 i18n,简化跨模块复用)
- String _editLabel(AppLocalizations l10n) => l10n.get('modify');
- String _submitLabel(AppLocalizations l10n) => l10n.get('submit');
- String _cancelSubmitLabel(AppLocalizations l10n) => l10n.get('cancelSubmit');
- String _returnLabel(AppLocalizations l10n) => l10n.get('returnCar');
- }
|