feat(client): 财务筛选增加往来单位并统一自定义时间组件(两端,原型同步)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-14 10:09:22 +08:00
parent 782cf057a3
commit a2aca2e7fc
10 changed files with 314 additions and 35 deletions
+20 -3
View File
@@ -83,7 +83,7 @@
<span class="lbl">时间范围</span>
<div class="chip on" data-range="本月" onclick="setRange('本月')">本月</div>
<div class="chip" data-range="本季" onclick="setRange('本季')">本季</div>
<div class="chip" data-range="自定义" onclick="setRange('自定义')">自定义 <svg viewBox="0 0 24 24"><use href="#i-ic16"/></svg></div>
<div class="chip" data-range="自定义" onclick="openCustomRange(this)">自定义 <svg viewBox="0 0 24 24"><use href="#i-ic16"/></svg></div>
</div>
<!-- 2. KPI 条 -->
@@ -123,6 +123,7 @@
<div class="chip on" data-flt="全部" onclick="setFlowFilter('全部')">全部</div>
<div class="chip" data-flt="收款" onclick="setFlowFilter('收款')">收款</div>
<div class="chip" data-flt="付款" onclick="setFlowFilter('付款')">付款</div>
<div class="chip" id="chipParty" onclick="openPartyFilter(this)">往来单位 <span class="cv" id="partyVal"></span><svg viewBox="0 0 24 24"><use href="#i-chevron-down"/></svg></div>
<div class="sp"></div>
<span class="ref" id="flowCount"></span>
</div>
@@ -141,7 +142,16 @@
<script src="shell.js"></script>
<script>
/* ---- 1. 时间范围 ---- */
function setRange(r){ document.querySelectorAll('.chip[data-range]').forEach(c=>c.classList.toggle('on',c.dataset.range===r)); document.getElementById('finSub').textContent='应收/应付概览 · '+r; if(r==='自定义')toast('自定义区间选择器(原型略)'); }
function setRange(r){ document.querySelectorAll('.chip[data-range]').forEach(c=>c.classList.toggle('on',c.dataset.range===r)); document.getElementById('finSub').textContent='应收/应付概览 · '+r; }
// 自定义区间:起止并排双滚轮锚定 chip 下方(datewheel.js openRange,对齐真实端 showDateRangeDropdown
let customFrom='', customTo='';
function openCustomRange(t){
DateWheel.openRange(t,{from:customFrom,to:customTo,onCommit:(f,to)=>{
customFrom=f; customTo=to;
document.querySelectorAll('.chip[data-range]').forEach(c=>c.classList.toggle('on',c.dataset.range==='自定义'));
document.getElementById('finSub').textContent='应收/应付概览 · '+f+' ~ '+to;
}});
}
/* ---- 3. 趋势图数据(万元) ---- */
const TREND=[
@@ -200,9 +210,13 @@ const FLOWS=[
{date:'2026-06-11',type:'收款',party:'华东酒类批发',amt:55200,ref:'SK-20260611-06',note:'梦之蓝M6'}
];
let flowFilter='全部';
let flowParty='全部';
const PARTIES=['全部',...Array.from(new Set(FLOWS.map(f=>f.party)))];
function setFlowFilter(f){ flowFilter=f; document.querySelectorAll('.chip[data-flt]').forEach(c=>c.classList.toggle('on',c.dataset.flt===f)); renderFlows(); }
// 往来单位:可搜索单选下拉(chip + openSearchMenu,照 stock-out-list.html 客户筛选写法)
function openPartyFilter(t){ openSearchMenu(t,PARTIES.map(v=>({v,label:v,sel:v===flowParty})),v=>{ flowParty=v; closeMenus(); renderFlows(); },{placeholder:'搜索往来单位…'}); }
function renderFlows(){
const rows=FLOWS.filter(f=>flowFilter==='全部'||f.type===flowFilter);
const rows=FLOWS.filter(f=>(flowFilter==='全部'||f.type===flowFilter)&&(flowParty==='全部'||f.party===flowParty));
const tb=document.getElementById('flowBody');
if(rows.length===0){ tb.innerHTML=`<tr><td colspan="6"><div class="empty">没有匹配的流水记录</div></td></tr>`; }
else { tb.innerHTML=rows.map(f=>`<tr>
@@ -215,6 +229,8 @@ function renderFlows(){
</tr>`).join(''); }
document.getElementById('flowCount').textContent=`${rows.length}`;
document.getElementById('flowSub').textContent=`本月 ${FLOWS.length} 笔 · 收 ${FLOWS.filter(f=>f.type==='收款').length} / 付 ${FLOWS.filter(f=>f.type==='付款').length}`;
document.getElementById('partyVal').textContent=flowParty==='全部'?'':flowParty;
document.getElementById('chipParty').classList.toggle('on',flowParty!=='全部');
}
/* ---- 抽屉:某往来单位流水 ---- */
@@ -246,6 +262,7 @@ document.addEventListener('keydown',e=>{ if(e.key==='Escape'){closeMenus();close
buildChart(); buildSummary(); renderFlows();
</script>
<a class="ds-fab" href="../index.html" title="返回设计系统" aria-label="返回设计系统"><svg viewBox="0 0 24 24"><use href="#i-arrow-left"/></svg></a>
<script src="datewheel.js"></script>
<script src="fab.js"></script>
<script src="notify.js"></script>
<script src="statusbar.js"></script>
+60 -3
View File
@@ -7,12 +7,30 @@
<link rel="stylesheet" href="../tokens.css">
<link rel="stylesheet" href="../atoms.css">
<link rel="stylesheet" href="../mobile-atoms.css">
<style>body{margin:0; font-family:var(--font); color:var(--text); background:var(--page); -webkit-font-smoothing:antialiased;}</style>
<style>
body{margin:0; font-family:var(--font); color:var(--text); background:var(--page); -webkit-font-smoothing:antialiased;}
/* 时间范围筛选行(回填真实端已有形态,照桌面 finance.html .timerow):
label+4 chip+登记 常超宽 → 整行横向可滚(照 m-stock-out-list.html 工具栏
chips 横向可滚同款写法),不把登记钉死右侧裁掉往来单位 chip */
.timerow{display:flex; align-items:center; gap:10px; margin:2px 0 14px; overflow-x:auto;}
.timerow::-webkit-scrollbar{display:none;}
.timerow .lbl{font-size:var(--fs-sm); color:var(--muted); margin-right:2px; flex:none; white-space:nowrap;}
.timerow > *{flex:none;}
</style>
</head>
<body>
<div class="m-top" data-m-top data-title="财务管理"></div>
<div class="m-page has-tabs">
<div class="m-scroll">
<!-- 时间范围(真实端 FinanceScreen._timeRow 移动分支:存量漂移回填) -->
<div class="timerow">
<span class="lbl">时间范围</span>
<div class="chip on" data-range="本月" onclick="setRange('本月')">本月</div>
<div class="chip" data-range="本季" onclick="setRange('本季')">本季</div>
<div class="chip" data-range="自定义" onclick="openCustomRange()">自定义 <svg viewBox="0 0 24 24"><use href="#i-ic16"/></svg></div>
<div class="chip" id="chipParty" onclick="openPartnerSheet()">往来单位 <span class="cv" id="partyVal"></span><svg viewBox="0 0 24 24"><use href="#i-chevron-down"/></svg></div>
<div class="btn primary sm" onclick="mToast('登记收支(原型)')"><svg viewBox="0 0 24 24"><use href="#i-plus"/></svg>登记</div>
</div>
<div class="m-kpi">
<div class="k"><div class="kl">本月收入</div><div class="kv">¥86.4万</div><div class="kd up">▲ 8.2% 较上月</div></div>
<div class="k"><div class="kl">本月支出</div><div class="kv">¥52.1万</div><div class="kd down">▲ 3.1% 较上月</div></div>
@@ -29,6 +47,7 @@
<script src="icons.js"></script>
<script src="mobile-shell.js"></script>
<script src="datewheel.js"></script>
<script>
const AR=[
{party:'城东烟酒行',amt:'¥86,200',status:'未结清',date:'账期 06-30'},
@@ -47,13 +66,51 @@ const FLOW=[
let tab='ar';
const FTABS=['ar','ap','flow'];
function setTab(t){ tab=t; const idx=FTABS.indexOf(t); document.querySelectorAll('.seg button').forEach((b,i)=>b.classList.toggle('on',i===idx)); render(); }
/* ---- 时间范围(照桌面 finance.html:仅改文案,不真实过滤 AR/AP/FLOW 展示数据) ---- */
function setRange(r){ document.querySelectorAll('.chip[data-range]').forEach(c=>c.classList.toggle('on',c.dataset.range===r)); }
// 自定义范围:窄屏走底部 sheet 纵排双滚轮(datewheel.js mountRange,对齐真实端
// showDateRangeDropdown 在 isMobile 下走 showMSheet,照 m-stock-in-list.html openAdvDateSheet 写法)
let customFrom='', customTo='';
function openCustomRange(){
openSheet('日期区间','<div id="rangeMount"></div>');
DateWheel.mountRange(document.getElementById('rangeMount'),{from:customFrom,to:customTo,onCommit:(f,to)=>{
customFrom=f; customTo=to;
document.querySelectorAll('.chip[data-range]').forEach(c=>c.classList.toggle('on',c.dataset.range==='自定义'));
closeSheet();
}});
}
/* ---- 往来单位(D6chip → 底部 sheet 可搜索单选,× 清除;仅过滤「流水」分段) ---- */
let flowParty='全部';
const PARTNERS=['全部',...Array.from(new Set([...AR,...AP,...FLOW].map(r=>r.party.split(' · ')[0])))];
function openPartnerSheet(){
openSheet('往来单位',
'<div class="m-search" style="margin-bottom:8px"><svg viewBox="0 0 24 24"><use href="#i-search"/></svg>'
+'<input id="partnerKw" placeholder="搜索往来单位…" oninput="drawPartnerOpts(this.value)"></div>'
+'<div id="partnerOptList"></div>');
drawPartnerOpts('');
}
function drawPartnerOpts(kw){
const q=(kw||'').trim().toLowerCase();
const hits=PARTNERS.filter(v=>v==='全部'||!q||v.toLowerCase().includes(q));
document.getElementById('partnerOptList').innerHTML=hits.length
? hits.map(v=>`<div class="m-opt ${v===flowParty?'sel':''}" onclick="setFlowParty('${v}')">${v}<svg class="ck" viewBox="0 0 24 24"><use href="#i-check"/></svg></div>`).join('')
: '<div style="padding:20px 4px;text-align:center;color:var(--muted);font-size:var(--fs-sm)">无匹配结果</div>';
}
function setFlowParty(v){ flowParty=v; closeSheet(); render(); }
function render(){
const cfg={ar:['应收账款',AR],ap:['应付账款',AP],flow:['资金流水',FLOW]}[tab];
document.getElementById('cnt').textContent=`${cfg[0]} · 共 ${cfg[1].length}`;
document.getElementById('list').innerHTML=cfg[1].map(r=>`<div class="m-card"><div class="m-row">
// 往来单位筛选仅作用于「流水」分段(对应真实端 financeListProvider.setPartner 只过滤流水表)
const rows=tab==='flow'?cfg[1].filter(r=>flowParty==='全部'||r.party.split(' · ')[0]===flowParty):cfg[1];
document.getElementById('cnt').textContent=`${cfg[0]} · 共 ${rows.length}`;
document.getElementById('list').innerHTML=rows.map(r=>`<div class="m-card"><div class="m-row">
<div class="mc-main"><div class="mc-nm">${r.party}</div><div class="mc-sub">${r.date}</div></div>
<div class="mc-right"><span class="badge b-${r.status}">${r.status}</span><span class="mc-amt">${r.amt}</span></div>
</div></div>`).join('');
document.getElementById('partyVal').textContent=flowParty==='全部'?'':flowParty;
document.getElementById('chipParty').classList.toggle('on',flowParty!=='全部');
}
render();
</script>