feat: 删除部门模块 + 任务系统重构 + 布局修复
- 删除部门(Home)侧边栏入口、面板及相关代码 - 删除 home.js,chartOptions 等图表工具迁移到 utils.js - 清理 render()、togglePhase、filterPhaseTasks 等死代码 - 任务列表改为平铺(取消阶段分组),支持拖拽排序 - 任务表单加开始时间字段,重组字段布局为三列 - 任务展开面板改为竖排:时间、任务进展、卡点与备注 - 视图按钮和新增任务按钮移入任务卡片顶部 - 修复 index.html div 嵌套不平衡导致布局塌陷 - 修复 savedTab 校验和 switchTenant 侧边栏 active 同步 - 总览工作台只显示预算/发生总览入口 - 性能面板 id 去重
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// utils.js — 全局工具函数与共享状态
|
||||
|
||||
const state = {
|
||||
active: "home",
|
||||
active: "plan",
|
||||
data: null,
|
||||
tenant: localStorage.getItem("opc-active-tenant") || "科普·无界",
|
||||
opFilter: "all",
|
||||
@@ -120,7 +120,6 @@ function renderTable(headers, rows, rowClicks) {
|
||||
}
|
||||
|
||||
var _loadingSteps = [
|
||||
{ fn: 'renderHome', label: '正在加载首页仪表盘(指标卡片+图表)', skip: function() { return true; } },
|
||||
{ fn: 'renderOverviewPlan', label: '正在加载预算总览', skip: function() { return state.tenant !== '总览'; } },
|
||||
{ fn: 'renderOverviewFinance', label: '正在加载发生总览', skip: function() { return state.tenant !== '总览'; } },
|
||||
{ fn: 'renderProjects', label: '正在加载业务机会列表' },
|
||||
@@ -235,7 +234,7 @@ var _tabLoaded = {};
|
||||
var _proposalsInitialized = false;
|
||||
|
||||
async function ensureTabData(tab) {
|
||||
if (tab === 'home' || tab === 'performance' || tab === 'overview_plan' || tab === 'overview_finance') return;
|
||||
if (tab === 'performance' || tab === 'overview_plan' || tab === 'overview_finance') return;
|
||||
var resource = _tabResourceMap[tab];
|
||||
if (!resource) return;
|
||||
var dataKey = resource;
|
||||
@@ -249,6 +248,8 @@ async function ensureTabData(tab) {
|
||||
try { state.data.expense = await api("/api/expense/list?tenant=" + encodeURIComponent(state.tenant)); } catch(e) {}
|
||||
try { state.data.finance = await api("/api/finance/list?tenant=" + encodeURIComponent(state.tenant)); } catch(e) {}
|
||||
try { state.data.tasks = await api("/api/tasks/list?tenant=" + encodeURIComponent(state.tenant)); } catch(e) {}
|
||||
} else if (tab === 'projects') {
|
||||
try { state.data.tasks = await api("/api/tasks/list?tenant=" + encodeURIComponent(state.tenant)); } catch(e) {}
|
||||
} else if (tab === 'plan') {
|
||||
try { state.data.planExpense = await api("/api/planExpense/list?tenant=" + encodeURIComponent(state.tenant)); } catch(e) {}
|
||||
}
|
||||
@@ -265,7 +266,7 @@ function switchTab(tab) {
|
||||
document.querySelectorAll(".panel").forEach((panel) => panel.classList.toggle("active", panel.id === tab));
|
||||
|
||||
// 更新顶部标题
|
||||
const titles = { home: 'OPC 工作台', finance: '执行管理', plan: '预算管理', projects: '重点工作台账', proposals: '业务方案', products: '版本与运营', performance: '季度绩效考核', overview_plan: '预算总览', overview_finance: '发生总览' };
|
||||
const titles = { finance: '执行管理', plan: '预算管理', projects: '重点工作台账', proposals: '业务方案', products: '版本与运营', performance: '季度绩效考核', overview_plan: '预算总览', overview_finance: '发生总览' };
|
||||
const titleEl = document.querySelector('#workspaceTitle');
|
||||
if (titleEl) titleEl.textContent = titles[tab] || state.tenant + ' OPC 工作台';
|
||||
|
||||
@@ -283,28 +284,15 @@ function updateSidebarTabs() {
|
||||
if (isOverview) {
|
||||
btn.style.display = (tab === "overview_plan" || tab === "overview_finance") ? "" : "none";
|
||||
} else {
|
||||
btn.style.display = (tab === "overview_plan" || tab === "overview_finance" || tab === "home") ? "none" : "";
|
||||
btn.style.display = (tab === "overview_plan" || tab === "overview_finance") ? "none" : "";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
if (!state.data) return;
|
||||
if (state.tenant === '总览') renderHome();
|
||||
renderProjects();
|
||||
renderProposals();
|
||||
renderProducts();
|
||||
renderPerformance();
|
||||
renderFinance();
|
||||
renderPlan();
|
||||
if (window.lucide) window.lucide.createIcons();
|
||||
}
|
||||
|
||||
function renderActive() {
|
||||
if (!state.data) return;
|
||||
const tab = state.active;
|
||||
if (tab === "home") renderHome();
|
||||
else if (tab === "overview_plan") renderOverviewPlan();
|
||||
if (tab === "overview_plan") renderOverviewPlan();
|
||||
else if (tab === "overview_finance") renderOverviewFinance();
|
||||
else if (tab === "projects") renderProjects();
|
||||
else if (tab === "proposals") renderProposals();
|
||||
@@ -403,11 +391,14 @@ window.switchTenant = async (tenant) => {
|
||||
localStorage.setItem("opc-active-tab", "overview_plan");
|
||||
document.querySelectorAll(".sidebar-tab").forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === "overview_plan"));
|
||||
document.querySelectorAll(".panel").forEach((panel) => panel.classList.toggle("active", panel.id === "overview_plan"));
|
||||
} else if (state.active === 'home' || state.active === 'overview_plan' || state.active === 'overview_finance') {
|
||||
} else if (state.active === 'overview_plan' || state.active === 'overview_finance') {
|
||||
state.active = 'plan';
|
||||
localStorage.setItem("opc-active-tab", "plan");
|
||||
document.querySelectorAll(".sidebar-tab").forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === "plan"));
|
||||
document.querySelectorAll(".panel").forEach((panel) => panel.classList.toggle("active", panel.id === "plan"));
|
||||
} else {
|
||||
document.querySelectorAll(".sidebar-tab").forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === state.active));
|
||||
document.querySelectorAll(".panel").forEach((panel) => panel.classList.toggle("active", panel.id === state.active));
|
||||
}
|
||||
await load();
|
||||
};
|
||||
@@ -424,3 +415,18 @@ window.doLogout = async () => {
|
||||
await api("/api/auth/logout", { method: "POST" });
|
||||
location.href = "/login";
|
||||
};
|
||||
|
||||
// 图表工具函数(曾被 home.js 中 plan/finance 模块复用)
|
||||
const moneyTick = (v) => v >= 10000 ? (v / 10000).toFixed(0) + "万" : v;
|
||||
const monthLabels = (data) => data.map((x) => parseInt(x.month.split("-")[1]) + "月");
|
||||
function chartOptions(yCallback) {
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: { legend: { position: "bottom", labels: { boxWidth: 12, font: { size: 11 } } } },
|
||||
scales: {
|
||||
x: { ticks: { font: { size: 10 } }, grid: { display: false } },
|
||||
y: { ticks: { font: { size: 11 }, callback: yCallback } },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user