This commit is contained in:
@@ -109,7 +109,7 @@ function renderPlan() {
|
||||
const activeQ = state.planQuarter !== undefined ? state.planQuarter : Math.floor(nowD.getMonth() / 3);
|
||||
const activeMonths = qMonths[activeQ];
|
||||
const yearOpts = [2024,2025,2026,2027];
|
||||
const finHeaderBase = `<div class="flex items-center gap-2"><button onclick="setPlanView('overview')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='overview'?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">总视图</button><span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">年份:</span><select onchange="setPlanYear(this.value)" class="px-2 py-0.5 rounded text-sm font-medium border border-slate-200 bg-white">${yearOpts.map(y => `<option value="${y}" ${state.planYear===y?'selected':''}>${y}</option>`).join('')}</select><span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">季度:</span>${qLabels.map((q,i) => `<button onclick="setPlanQuarter(${i})" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='quarterly'&&activeQ===i?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">${q}</button>`).join('')}<span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">月度:</span>${activeMonths.map(m => { const ms = `${state.planYear}-${String(m).padStart(2,'0')}`; return `<button onclick="setPlanMonth('${ms}')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='monthly'&&state.planMonth===ms?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">${m}月</button>`; }).join('')}</div>`;
|
||||
const finHeaderBase = `<div class="flex items-center gap-2"><button onclick="setPlanView('overview')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='overview'?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">总视图</button><span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">年份:</span><select onchange="setPlanYear(this.value)" class="px-2 py-0.5 rounded text-sm font-medium border border-slate-200 bg-white">${yearOpts.map(y => `<option value="${y}" ${state.planYear===y?'selected':''}>${y}</option>`).join('')}</select><span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">季度:</span>${qLabels.map((q,i) => `<button onclick="setPlanQuarter(${i})" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='quarterly'&&activeQ===i?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">${q}</button>`).join('')}<span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">月度:</span>${activeMonths.map(m => { const ms = `${state.planYear}-${String(m).padStart(2,'0')}`; return `<button onclick="setPlanMonth('${ms}')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planView==='monthly'&&state.planMonth===ms?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">${m}月</button>`; }).join('')}<span class="text-slate-300 mx-2">|</span><button onclick="setPlanStatusFilter('unsigned')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planStatusFilter==='unsigned'?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">待签约</button><button onclick="setPlanStatusFilter('signed')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planStatusFilter==='signed'?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">已签约</button><button onclick="setPlanStatusFilter('paymentonly')" class="px-3 py-0.5 rounded text-sm font-medium ${state.planStatusFilter==='paymentonly'?'bg-blue-600 text-white':'bg-slate-100 text-slate-600 hover:bg-slate-200'}">只付款</button></div>`;
|
||||
const finAddBtn = `<button class="btn btn-primary btn-sm" onclick="openPlanModal()">新增财务项目</button>`;
|
||||
|
||||
const isOverviewMode = false;
|
||||
@@ -345,6 +345,21 @@ function renderPlan() {
|
||||
};
|
||||
|
||||
const fmtNoUnit = (v) => v ? `<span class="font-medium">${Number(v||0).toLocaleString('zh-CN')}</span>` : '<span class="text-slate-300">—</span>';
|
||||
|
||||
// 状态过滤函数
|
||||
const filterByStatus = (items) => {
|
||||
var sf = state.planStatusFilter || 'all';
|
||||
if (sf === 'all') return items;
|
||||
return items.filter(d => {
|
||||
if (sf === 'unsigned') return (d.pf.project_type || '待签约') === '待签约';
|
||||
if (sf === 'signed') return (d.pf.project_type || '待签约') === '已签约';
|
||||
if (sf === 'paymentonly') {
|
||||
return (!d.rev && !d.gross && !d.payment) && (d.cost || d.paid);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
const tdRow = (pf, rev, payment, cost, paid, gross) => {
|
||||
const cashflow = payment - paid;
|
||||
const payRVal = rev && payment ? Math.round(payment / rev * 100) : null;
|
||||
@@ -422,7 +437,7 @@ function renderPlan() {
|
||||
});
|
||||
});
|
||||
var sortK = state.planSort && state.planSort.key ? state.planSort.key.split('|')[1] : null;
|
||||
dataItems = sortData(dataItems, sortK);
|
||||
dataItems = filterByStatus(sortData(dataItems, sortK));
|
||||
const rows = [];
|
||||
let sumRev = 0, sumPay = 0, sumCost = 0, sumPaid = 0, sumGross = 0;
|
||||
dataItems.forEach(d => {
|
||||
@@ -477,7 +492,7 @@ function renderPlan() {
|
||||
});
|
||||
});
|
||||
var sortK = state.planSort && state.planSort.key ? state.planSort.key.split('|')[1] : null;
|
||||
dataItems = sortData(dataItems, sortK);
|
||||
dataItems = filterByStatus(sortData(dataItems, sortK));
|
||||
let sumRev = 0, sumPay = 0, sumCost = 0, sumPaid = 0, sumGross = 0;
|
||||
const rows = [];
|
||||
dataItems.forEach(d => {
|
||||
@@ -518,7 +533,7 @@ function renderPlan() {
|
||||
});
|
||||
var sortK = null;
|
||||
if (state.planSort && state.planSort.key && state.planSort.key.startsWith('sig|')) sortK = state.planSort.key.split('|')[1];
|
||||
dataItems = sortData(dataItems, sortK);
|
||||
dataItems = filterByStatus(sortData(dataItems, sortK));
|
||||
let sumRev = 0, sumPay = 0, sumCost = 0, sumPaid = 0, sumGross = 0;
|
||||
const rows = [];
|
||||
dataItems.forEach(d => {
|
||||
|
||||
@@ -14,6 +14,7 @@ const state = {
|
||||
planFilter: "projects",
|
||||
planYear: new Date().getFullYear(),
|
||||
finYear: new Date().getFullYear(),
|
||||
planStatusFilter: "all",
|
||||
planView: "overview",
|
||||
planSort: null,
|
||||
proposalTab: "standard",
|
||||
@@ -355,6 +356,7 @@ window.setPlanView = (view) => {
|
||||
window.setPlanQuarter = (q) => { state.planQuarter = q; state.planView = 'quarterly'; renderPlan(); };
|
||||
window.setPlanMonth = (month) => { state.planMonth = month; state.planView = 'monthly'; renderPlan(); };
|
||||
window.setPlanYear = (year) => { state.planYear = parseInt(year); renderPlan(); };
|
||||
window.setPlanStatusFilter = (filter) => { state.planStatusFilter = filter; renderPlan(); };
|
||||
window.switchPlanFilter = (filter) => {
|
||||
state.planFilter = filter;
|
||||
state.planSort = null;
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<header class="topbar border-b border-slate-200 bg-white px-8 py-5">
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<div class="flex-1">
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.2.0.16</span></p>
|
||||
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager <span class="ml-2 text-xs font-normal text-slate-400 tracking-normal">v1.2.0.17</span></p>
|
||||
<div class="flex items-center gap-4 mt-1">
|
||||
<h1 class="text-2xl font-semibold" id="workspaceTitle">科普 OPC 工作台</h1>
|
||||
<div class="hidden sm:flex items-center gap-1.5 bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-100 rounded-full px-4 py-1.5">
|
||||
|
||||
Reference in New Issue
Block a user