From 5af58c8faa2e9518daeebc6c690b583770bde2a9 Mon Sep 17 00:00:00 2001 From: mac Date: Tue, 16 Jun 2026 11:15:55 +0800 Subject: [PATCH] =?UTF-8?q?v1.7.0=20=E2=80=94=20=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E6=94=B9=E4=B8=BA=20Tab=20=E5=86=85=E4=BA=8C?= =?UTF-8?q?=E7=BA=A7=E9=A1=B5=E9=9D=A2=EF=BC=8C=E4=B8=8D=E5=86=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=8B=AC=E7=AB=8B=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/app.js | 51 ++++++++++++++++++++++++++++++++++++++++++++--- static/styles.css | 2 +- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/static/app.js b/static/app.js index 4cbbf00..d703ad0 100644 --- a/static/app.js +++ b/static/app.js @@ -2,6 +2,7 @@ const state = { active: "home", data: null, opFilter: "all", + projectView: null, chart: null, chart2: null, productPlatform: "all", @@ -216,8 +217,6 @@ window.submitTaskForm = async (event, projectId) => { await api("/api/tasks", { method: "POST", body: JSON.stringify({ data }) }); } await load(); - closeTaskDrawer(projectId); - showTaskModal(Number(projectId)); } catch (error) { alert("保存失败:" + error.message); } @@ -226,6 +225,10 @@ window.createFinance = (event) => createResource(event, "finance"); window.switchTab = switchTab; function renderProjects() { + // 二级页面:项目任务详情 + if (state.projectView) { + return renderProjectTasks(state.projectView); + } const items = state.data.operations; const rows = items.map((x) => [ `${x.project_name}`, @@ -233,7 +236,7 @@ function renderProjects() { badge(x.current_stage || x.project_status), x.expected_contract_amount ? money(x.expected_contract_amount) : "—", text(x.owner || "—"), - `` + `` ]); document.querySelector("#projects").innerHTML = `
@@ -253,6 +256,48 @@ function renderProjects() {
`; } +function renderProjectTasks(projectId) { + const project = state.data.operations.find((x) => x.id === projectId); + if (!project) { state.projectView = null; renderProjects(); return; } + const tasks = (state.data.tasks || []).filter((t) => t.project_id === projectId); + const phases = ["商务洽谈", "系统上线", "团队分工", "项目交付", "上线推广", "结项验收"]; + document.querySelector("#projects").innerHTML = `
+
+ +
+ ${project.project_name} + +
+
+
+
+ ${phases.map((phase) => { + const pt = tasks.filter((t) => t.phase === phase); + if (!pt.length) return ""; + return `
${phase}${pt.length}
${pt.map((t) => `
${t.task}${t.notes ? `${t.notes}` : ""}${t.blockers ? `⚠ ${t.blockers}` : ""}
${t.owner || ""}${t.due_date || ""}
`).join("")}
`; + }).join("")} +
+
+
编辑任务
+
+ + + + + + + +
+ + +
+
+
+
+
`; + if (window.lucide) window.lucide.createIcons(); +} + function showTaskModal(projectId) { const project = state.data.operations.find((x) => x.id === projectId); const tasks = (state.data.tasks || []).filter((t) => t.project_id === projectId); diff --git a/static/styles.css b/static/styles.css index c1ff82f..4a7a01f 100644 --- a/static/styles.css +++ b/static/styles.css @@ -513,7 +513,7 @@ td { padding: 4px; border-radius: 6px; display: flex; } .task-close:hover { color: #475569; background: #f1f5f9; } -.task-body-wrap { position: relative; overflow: hidden; } +.task-body-wrap, .task-page-wrap { position: relative; overflow: hidden; } .task-body { padding: 20px; display: flex; flex-direction: column; gap: 16px; transition: margin-right 0.25s ease; } .task-drawer { position: absolute; top: 0; right: 0; width: 420px; height: 100%;