Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceb54e29ec |
@@ -266,10 +266,14 @@ function renderFinance() {
|
|||||||
{ label: '付款率', hideUnsigned: true, value: ctx => ctx.sumCost && ctx.sumPaid ? Math.round(ctx.sumPaid / ctx.sumCost * 100) + '%' : '—', color: 'text-slate-500' },
|
{ label: '付款率', hideUnsigned: true, value: ctx => ctx.sumCost && ctx.sumPaid ? Math.round(ctx.sumPaid / ctx.sumCost * 100) + '%' : '—', color: 'text-slate-500' },
|
||||||
].filter(c => true);
|
].filter(c => true);
|
||||||
|
|
||||||
// 列排序
|
// 列排序(默认按确收金额从高到低)
|
||||||
if (!state.finSort) state.finSort = { key: null, asc: true };
|
if (!state.finSort) state.finSort = { key: 'sig|rev', asc: false };
|
||||||
const sortData = (data, key) => {
|
const sortData = (data, key) => {
|
||||||
if (!key || !state.finSort.key) return data;
|
if (!key) return data;
|
||||||
|
if (!state.finSort.key) {
|
||||||
|
// 默认按确收金额从高到低
|
||||||
|
return data.slice().sort(function(a, b) { return (parseFloat(b.rev) || 0) - (parseFloat(a.rev) || 0); });
|
||||||
|
}
|
||||||
var asc = state.finSort.asc ? 1 : -1;
|
var asc = state.finSort.asc ? 1 : -1;
|
||||||
return data.slice().sort(function(a, b) {
|
return data.slice().sort(function(a, b) {
|
||||||
var va = a[key], vb = b[key];
|
var va = a[key], vb = b[key];
|
||||||
@@ -336,14 +340,19 @@ function renderFinance() {
|
|||||||
var expenseArr = [];
|
var expenseArr = [];
|
||||||
try { budgetArr = JSON.parse(pf.budget_data || "[]"); } catch(e) {}
|
try { budgetArr = JSON.parse(pf.budget_data || "[]"); } catch(e) {}
|
||||||
try { expenseArr = JSON.parse(pf.expense_data || "[]"); } catch(e) {}
|
try { expenseArr = JSON.parse(pf.expense_data || "[]"); } catch(e) {}
|
||||||
var detailRows = budgetArr.filter(function(b) {
|
// 合并 budget 和 expense 的所有月份
|
||||||
var exp = expenseArr.find(function(e) { return e.month === (b.month || ''); }) || {};
|
var allMonths = {};
|
||||||
|
budgetArr.forEach(function(b) { allMonths[b.month || ''] = true; });
|
||||||
|
expenseArr.forEach(function(e) { allMonths[e.month || ''] = true; });
|
||||||
|
var detailRows = Object.keys(allMonths).filter(function(m) {
|
||||||
|
var b = budgetArr.find(function(x) { return x.month === m; }) || {};
|
||||||
|
var exp = expenseArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
||||||
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
||||||
return bRev || bGross || bPay || eCost || ePaid;
|
return bRev || bGross || bPay || eCost || ePaid;
|
||||||
}).map(function(b) {
|
}).sort().map(function(m) {
|
||||||
var m = b.month || '';
|
var b = budgetArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var exp = expenseArr.find(function(e) { return e.month === m; }) || {};
|
var exp = expenseArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
||||||
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
||||||
var bCf = bPay - ePaid;
|
var bCf = bPay - ePaid;
|
||||||
@@ -707,7 +716,7 @@ window.editPfSignMonth = (event, pfId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.switchFinanceTab = (tab) => {
|
window.switchFinanceTab = (tab) => {
|
||||||
document.querySelectorAll(".finance-tab").forEach(b => b.classList.toggle("active", b.dataset.tab === tab));
|
document.querySelectorAll("#financeModal .finance-tab").forEach(b => b.classList.toggle("active", b.dataset.tab === tab));
|
||||||
document.querySelector("#financeTabInfo").classList.toggle("hidden", tab !== "info");
|
document.querySelector("#financeTabInfo").classList.toggle("hidden", tab !== "info");
|
||||||
document.querySelector("#financeTabRevpay").classList.toggle("hidden", tab !== "revpay");
|
document.querySelector("#financeTabRevpay").classList.toggle("hidden", tab !== "revpay");
|
||||||
document.querySelector("#financeTabCost").classList.toggle("hidden", tab !== "cost");
|
document.querySelector("#financeTabCost").classList.toggle("hidden", tab !== "cost");
|
||||||
|
|||||||
@@ -264,10 +264,14 @@ function renderPlan() {
|
|||||||
{ label: '付款率', hideUnsigned: true, value: ctx => ctx.sumCost && ctx.sumPaid ? Math.round(ctx.sumPaid / ctx.sumCost * 100) + '%' : '—', color: 'text-slate-500' },
|
{ label: '付款率', hideUnsigned: true, value: ctx => ctx.sumCost && ctx.sumPaid ? Math.round(ctx.sumPaid / ctx.sumCost * 100) + '%' : '—', color: 'text-slate-500' },
|
||||||
].filter(c => true);
|
].filter(c => true);
|
||||||
|
|
||||||
// 列排序
|
// 列排序(默认按确收金额从高到低)
|
||||||
if (!state.planSort) state.planSort = { key: null, asc: true };
|
if (!state.planSort) state.planSort = { key: 'sig|rev', asc: false };
|
||||||
const sortData = (data, key) => {
|
const sortData = (data, key) => {
|
||||||
if (!key || !state.planSort.key) return data;
|
if (!key) return data;
|
||||||
|
if (!state.planSort.key) {
|
||||||
|
// 默认按确收金额从高到低
|
||||||
|
return data.slice().sort(function(a, b) { return (parseFloat(b.rev) || 0) - (parseFloat(a.rev) || 0); });
|
||||||
|
}
|
||||||
var asc = state.planSort.asc ? 1 : -1;
|
var asc = state.planSort.asc ? 1 : -1;
|
||||||
return data.slice().sort(function(a, b) {
|
return data.slice().sort(function(a, b) {
|
||||||
var va = a[key], vb = b[key];
|
var va = a[key], vb = b[key];
|
||||||
@@ -351,14 +355,19 @@ function renderPlan() {
|
|||||||
var expenseArr = [];
|
var expenseArr = [];
|
||||||
try { budgetArr = JSON.parse(pf.budget_data || "[]"); } catch(e) {}
|
try { budgetArr = JSON.parse(pf.budget_data || "[]"); } catch(e) {}
|
||||||
try { expenseArr = JSON.parse(pf.expense_data || "[]"); } catch(e) {}
|
try { expenseArr = JSON.parse(pf.expense_data || "[]"); } catch(e) {}
|
||||||
var detailRows = budgetArr.filter(function(b) {
|
// 合并 budget 和 expense 的所有月份
|
||||||
var exp = expenseArr.find(function(e) { return e.month === (b.month || ''); }) || {};
|
var allMonths = {};
|
||||||
|
budgetArr.forEach(function(b) { allMonths[b.month || ''] = true; });
|
||||||
|
expenseArr.forEach(function(e) { allMonths[e.month || ''] = true; });
|
||||||
|
var detailRows = Object.keys(allMonths).filter(function(m) {
|
||||||
|
var b = budgetArr.find(function(x) { return x.month === m; }) || {};
|
||||||
|
var exp = expenseArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
||||||
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
||||||
return bRev || bGross || bPay || eCost || ePaid;
|
return bRev || bGross || bPay || eCost || ePaid;
|
||||||
}).map(function(b) {
|
}).sort().map(function(m) {
|
||||||
var m = b.month || '';
|
var b = budgetArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var exp = expenseArr.find(function(e) { return e.month === m; }) || {};
|
var exp = expenseArr.find(function(x) { return x.month === m; }) || {};
|
||||||
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
var bRev = parseFloat(b.rev || 0), bGross = parseFloat(b.gross || 0), bPay = parseFloat(b.payment || 0);
|
||||||
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
var eCost = parseFloat(exp.cost || 0), ePaid = parseFloat(exp.paid || 0);
|
||||||
var bCf = bPay - ePaid;
|
var bCf = bPay - ePaid;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
<header class="topbar border-b border-slate-200 bg-white px-8 py-5">
|
<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 items-center gap-3 w-full">
|
||||||
<div class="flex-1">
|
<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.9</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.10</span></p>
|
||||||
<div class="flex items-center gap-4 mt-1">
|
<div class="flex items-center gap-4 mt-1">
|
||||||
<h1 class="text-2xl font-semibold" id="workspaceTitle">科普 OPC 工作台</h1>
|
<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">
|
<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