Explorar o código

fix #19407 报销单新增明细支持自动带当前登录用户为申请人

chengc hai 1 semana
pai
achega
6c5643916b

+ 10 - 1
lib/features/expense/expense_create_page.dart

@@ -54,6 +54,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
   List<CurrencyItem> _currencies = [];
   List<EmployeeItem> _employees = [];
   EmployeeItem? _selEmployee;
+  EmployeeItem? _currentUserForDialog;
   dynamic _acctTree;
   bool _firstBuild = true;
   bool _refDataLoading = true;
@@ -117,6 +118,7 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
         api.getDepartments(),
         api.getCurrencies(),
         api.getEmployees(),
+        api.getEmployees(salNo: HostAppChannel.usr, size: 1),
         api.getAcctSubjects(),
       ]);
       if (!mounted) {
@@ -127,7 +129,12 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
         _departments = results[0] as List<DepartmentItem>;
         _currencies = results[1] as List<CurrencyItem>;
         _employees = results[2] as List<EmployeeItem>;
-        _acctTree = _convertAcctTree(results[3]);
+        final currentUserCheck = results[3] as List<EmployeeItem>;
+        if (currentUserCheck.isNotEmpty) {
+          _selEmployee = currentUserCheck.first;
+          _currentUserForDialog = currentUserCheck.first;
+        }
+        _acctTree = _convertAcctTree(results[4]);
         _refDataLoading = false;
         _autoSelectDept();
         _autoSelectEmployee();
@@ -1211,6 +1218,8 @@ class _ExpenseCreatePageState extends ConsumerState<ExpenseCreatePage> {
         canEditApprovedAmount: _canEditApprovedAmount,
         billFileRights: _billFileRights,
         acctTree: _acctTree,
+        defaultSqMan: _currentUserForDialog?.salNo,
+        defaultSqManName: _currentUserForDialog?.name,
       );
       if (result != null && mounted) {
         final now = DateTime.now();

+ 8 - 0
lib/features/expense/expense_edit_page.dart

@@ -54,6 +54,7 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
   // ── 参考数据(从 API 加载) ──
   List<CurrencyItem> _currencies = [];
   EmployeeItem? _selEmployee;
+  EmployeeItem? _currentUserForDialog;
   dynamic _acctTree;
   bool _firstBuild = true;
   bool _refDataLoading = true;
@@ -103,12 +104,17 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
         api.getCurrencies(),
         api.fetchDetail(widget.billNo),
         api.getAcctSubjects(),
+        api.getEmployees(salNo: HostAppChannel.usr, size: 1),
       ]);
       if (!mounted) return;
       final expense = results[1] as ExpenseModel;
       setState(() {
         _currencies = results[0] as List<CurrencyItem>;
         _acctTree = _convertAcctTree(results[2]);
+        final currentUserCheck = results[3] as List<EmployeeItem>;
+        if (currentUserCheck.isNotEmpty) {
+          _currentUserForDialog = currentUserCheck.first;
+        }
         _expense = expense;
         _expenseDate = expense.expenseDate != null
             ? du.DateUtils.formatDate(expense.expenseDate!)
@@ -892,6 +898,8 @@ class _ExpenseEditPageState extends ConsumerState<ExpenseEditPage> {
         showAttachments: false,
         canEditApprovedAmount: _canEditApprovedAmount,
         acctTree: _acctTree,
+        defaultSqMan: _currentUserForDialog?.salNo,
+        defaultSqManName: _currentUserForDialog?.name,
       );
       if (result != null && mounted) {
         final now = DateTime.now();

+ 59 - 7
lib/features/expense/widgets/expense_detail_dialog.dart

@@ -1,4 +1,4 @@
-// ignore_for_file: use_build_context_synchronously
+// ignore_for_file: use_build_context_synchronously
 
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -80,6 +80,8 @@ class ExpenseDetailDialog extends StatefulWidget {
   final bool canEditApprovedAmount;
   final BillFileRights? billFileRights;
   final dynamic acctTree;
+  final String? defaultSqMan;
+  final String? defaultSqManName;
 
   const ExpenseDetailDialog({
     super.key,
@@ -91,6 +93,8 @@ class ExpenseDetailDialog extends StatefulWidget {
     this.canEditApprovedAmount = false,
     this.billFileRights,
     required this.acctTree,
+    this.defaultSqMan,
+    this.defaultSqManName,
   });
 
   /// 显示弹窗,返回 [ExpenseDetailInputData] 或 `null`(取消时)。
@@ -104,6 +108,8 @@ class ExpenseDetailDialog extends StatefulWidget {
     bool canEditApprovedAmount = false,
     BillFileRights? billFileRights,
     required dynamic acctTree,
+    String? defaultSqMan,
+    String? defaultSqManName,
   }) {
     FocusScope.of(context).unfocus();
     return Navigator.push<ExpenseDetailInputData>(
@@ -118,6 +124,8 @@ class ExpenseDetailDialog extends StatefulWidget {
           checkAttachHealth: checkAttachHealth,
           showAttachments: showAttachments,
           canEditApprovedAmount: canEditApprovedAmount,
+          defaultSqMan: defaultSqMan,
+          defaultSqManName: defaultSqManName,
           billFileRights: billFileRights,
           acctTree: acctTree,
         ),
@@ -216,7 +224,17 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
     _taxRate = d?.taxRate ?? 0;
     _selEmployee = (d != null && d.sqMan.isNotEmpty)
         ? EmployeeItem(salNo: d.sqMan, name: d.sqManName)
-        : null;
+        : (widget.defaultSqMan != null
+              ? EmployeeItem(
+                  salNo: widget.defaultSqMan!,
+                  name: widget.defaultSqManName ?? '',
+                )
+              : null);
+    if (_selEmployee != null && (d == null || d.sqMan.isEmpty)) {
+      WidgetsBinding.instance.addPostFrameCallback(
+        (_) => _loadDefaultBankInfo(),
+      );
+    }
     _selProject = (d != null && d.projectId.isNotEmpty)
         ? ProjectCodeItem(objNo: d.projectId, name: d.projectName)
         : null;
@@ -239,6 +257,23 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
     _checkAttachHealth();
   }
 
+  Future<void> _loadDefaultBankInfo() async {
+    if (_selEmployee == null || _selEmployee!.salNo.isEmpty) return;
+    try {
+      final list = await widget.api.getEmployees(
+        salNo: _selEmployee!.salNo,
+        size: 1,
+      );
+      if (!mounted || list.isEmpty) return;
+      setState(() {
+        _selEmployee = list.first;
+        _bankNameCtrl.text = list.first.bnkNo;
+        _bankAccountNameCtrl.text = list.first.accName;
+        _bankAccountCtrl.text = list.first.bnkId;
+      });
+    } catch (_) {}
+  }
+
   Future<void> _checkAttachHealth() async {
     if (widget.checkAttachHealth == null) return;
     if (mounted) setState(() => _attachAvailable = false);
@@ -517,7 +552,9 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
                       overflow: TextOverflow.ellipsis,
                       font: tdTheme.fontBodyLarge,
                       fontWeight: FontWeight.w400,
-                      textColor: hasValue ? tdTheme.textColorPrimary : tdTheme.textColorPlaceholder,
+                      textColor: hasValue
+                          ? tdTheme.textColorPrimary
+                          : tdTheme.textColorPlaceholder,
                       textAlign: TextAlign.end,
                     ),
                   ),
@@ -1026,7 +1063,12 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
         );
       },
       child: Container(
-        padding: const EdgeInsets.only(left: 16, right: 10, top: 12, bottom: 12),
+        padding: const EdgeInsets.only(
+          left: 16,
+          right: 10,
+          top: 12,
+          bottom: 12,
+        ),
         decoration: BoxDecoration(
           color: tdTheme.bgColorContainer,
           borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
@@ -1055,7 +1097,9 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
                       overflow: TextOverflow.ellipsis,
                       font: tdTheme.fontBodyLarge,
                       fontWeight: FontWeight.w400,
-                      textColor: hasValue ? tdTheme.textColorPrimary : tdTheme.textColorPlaceholder,
+                      textColor: hasValue
+                          ? tdTheme.textColorPrimary
+                          : tdTheme.textColorPlaceholder,
                       textAlign: TextAlign.end,
                     ),
                   ),
@@ -1075,9 +1119,17 @@ class _ExpenseDetailDialogState extends State<ExpenseDetailDialog> {
                                 );
                               });
                             },
-                            child: Icon(Icons.close, size: 18, color: tdTheme.textColorPlaceholder),
+                            child: Icon(
+                              Icons.close,
+                              size: 18,
+                              color: tdTheme.textColorPlaceholder,
+                            ),
                           )
-                        : Icon(Icons.chevron_right, size: 18, color: tdTheme.textColorPlaceholder),
+                        : Icon(
+                            Icons.chevron_right,
+                            size: 18,
+                            color: tdTheme.textColorPlaceholder,
+                          ),
                   ),
                 ],
               ),