fix(client): 财务汇总往来搜索改为表头下拉框形态(验收反馈)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-14 12:35:11 +08:00
parent edb85c88da
commit 4bd083f2eb
7 changed files with 132 additions and 55 deletions
+69 -22
View File
@@ -58,9 +58,13 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
// 窄屏三分段(原型 m-finance .seg:应收 / 应付 / 流水)
int _mSeg = 0;
// 应收/应付汇总卡「往来单位」搜索(本地即时过滤——financePartnerRowsProvider
// 全量加载非分页,搜索口径=显示口径;桌面 DsSearchBox / 移动 MSearchRow 用)
// 全量加载非分页,搜索口径=显示口径;移动 应收·应付 分段头 MSearchRow 沿用)
final _summaryKwCtrl = TextEditingController();
String _summaryKw = '';
// 桌面汇总表表头「往来单位」下拉筛选(验收反馈改版:由卡标题行文字搜索
// 改为表头内嵌 ComboSearchField,同 _flowTable 往来单位筛选控件;单选精确
// 匹配一行,× 清除恢复全量;候选=当前汇总行往来单位,口径=显示口径)。
int? _summaryPartnerId;
static const _flowChips = ['全部', '应收', '应付', '收款', '付款'];
static const _chipToType = {
@@ -129,13 +133,30 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
void _setSummaryKw(String kw) => setState(() => _summaryKw = kw);
/// 汇总行本地过滤(往来单位名 contains,大小写不敏感)。
/// 汇总行本地过滤(往来单位名 contains,大小写不敏感;移动端专用)。
List<PartnerFinanceRow> _filterSummaryRows(List<PartnerFinanceRow> rows) {
final kw = _summaryKw.trim().toLowerCase();
if (kw.isEmpty) return rows;
return rows.where((r) => r.name.toLowerCase().contains(kw)).toList();
}
void _setSummaryPartner(int? id) => setState(() => _summaryPartnerId = id);
/// 桌面汇总表头下拉筛选:选中 → 精确匹配单行;未选 → 原样返回(专用)。
/// [id] 优先取 partnerId,缺失(自由文本往来单位)时用行下标取负数兜底,
/// 与 header 里构建 ComboSearchField options 的合成 id 规则保持一致。
List<PartnerFinanceRow> _filterSummaryByPartner(
List<PartnerFinanceRow> rows,
) {
if (_summaryPartnerId == null) return rows;
for (var i = 0; i < rows.length; i++) {
if ((rows[i].partnerId ?? -(i + 1)) == _summaryPartnerId) {
return [rows[i]];
}
}
return const [];
}
@override
void dispose() {
_summaryKwCtrl.dispose();
@@ -242,17 +263,7 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
_secHead(t, '收支趋势', '近 6 个月 · 单位 万元'),
_trendChart(),
const SizedBox(height: 22),
_secHead(
t,
'应收 / 应付 汇总',
'按往来单位 · 点击行查看流水',
trailing: DsSearchBox(
controller: _summaryKwCtrl,
hint: '搜索往来单位',
width: 220,
onChanged: _setSummaryKw,
),
),
_secHead(t, '应收 / 应付 汇总', '按往来单位 · 点击行查看流水'),
_summaryTable(t, mobile),
const SizedBox(height: 22),
_secHead(t, '收支流水', _flowSub(flows)),
@@ -531,7 +542,7 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
}
/// 原型 .sec-headh2 17/700 + 副标 fs-xs muted,下距 12。
/// [trailing] 靠右附加控件(原型 .sec-head .sum-search,如汇总卡的往来单位搜索)。
/// [trailing] 靠右附加控件(当前各段落调用均未传入,保留供后续段落复用)。
Widget _secHead(dynamic t, String title, String sub, {Widget? trailing}) =>
Padding(
padding: const EdgeInsets.only(bottom: 12),
@@ -628,10 +639,20 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
],
),
data: (allRows) {
final rows = _filterSummaryRows(allRows);
final rows = _filterSummaryByPartner(allRows);
// 下拉候选=当前汇总行往来单位(口径=显示口径,不用全量 partners,避免
// 选到无余额单位出空表);id 合成规则同 _filterSummaryByPartner。
final partnerOptions = <OptionItem>[
for (var i = 0; i < allRows.length; i++)
OptionItem(
id: allRows[i].partnerId ?? -(i + 1),
name: allRows[i].name,
),
];
return DsTable(
shrinkWrap: true,
emptyText: _summaryKw.trim().isEmpty ? '暂无未结清的应收 / 应付' : '没有匹配的往来单位',
emptyText:
_summaryPartnerId == null ? '暂无未结清的应收 / 应付' : '没有匹配的往来单位',
mobileCards: rows
.map(
(r) => MobileListCard(
@@ -655,12 +676,38 @@ class _FinanceScreenState extends ConsumerState<FinanceScreen> {
),
)
.toList(),
columns: const [
DsColumn('name', '往来单位'),
DsColumn('recv', '应收', numeric: true),
DsColumn('pay', '应付', numeric: true),
DsColumn('net', '净额', numeric: true),
DsColumn('actions', '操作', action: true),
columns: [
DsColumn(
'name',
'往来单位',
// 表头「往来单位」文字右边内嵌下拉(验收反馈:由卡标题行搜索框
// 改到此处,与 _flowTable 往来单位筛选同款 ComboSearchField)。
header: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'往来单位',
style: TextStyle(
fontSize: AppDims.fsSm,
fontWeight: FontWeight.w600,
color: t.muted,
),
),
const SizedBox(width: 10),
ComboSearchField(
options: partnerOptions,
selectedId: _summaryPartnerId,
hint: '搜索往来单位',
width: 180,
onChanged: _setSummaryPartner,
),
],
),
),
const DsColumn('recv', '应收', numeric: true),
const DsColumn('pay', '应付', numeric: true),
const DsColumn('net', '净额', numeric: true),
const DsColumn('actions', '操作', action: true),
],
rows: rows.map((r) {
return DsRow(