首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何开发一套工程项目部管理系统?(附架构图+流程图+代码参考)

如何开发一套工程项目部管理系统?(附架构图+流程图+代码参考)

原创
作者头像
用户11735492
发布2025-08-27 16:26:22
发布2025-08-27 16:26:22
1470
举报

WBS(工作分解结构)是工程项目把“大工程”拆成“能执行的小单元”的利器;把它做成系统板块,就是把口头计划、各种 Excel、微信指令变成可追溯、可下发、可统计的业务流。本文给你一套能立刻上手的落地方案:从为什么做、放在哪、具体功能、架构与流程、到最小可跑代码(数据库、后端、关键路径算法、前端树视图)——代码我会集中给出,能直接复制跑通 MVP。


本文你将了解

  1. 为什么要把WBS做成系统板块(价值 + 痛点)
  2. 工程项目部管理系统里WBS的角色与边界
  3. WBS分解板块功能清单(MVP + 迭代)
  4. 系统架构(含架构图)
  5. 业务流程(含流程图)
  6. 数据模型与接口设计(含 SQL)
  7. 前端实现思路与核心组件(含 React 示例)
  8. 后端实现思路与关键逻辑(含 Node.js/Express + 关键路径计算)
  9. 开发技巧:并发、性能、审计、扩展(实战要点)
  10. 上线后如何验收与效果衡量
  11. 整合代码参考(最小可跑 MVP)

一、为什么要把WBS做成系统板块

简单明了:把“拆解、责任、工期、依赖”从人的头脑里拿出来,搬到系统里去管。价值体现在:

  • 责任明确:每个小工作有负责人、起止时间、验收标准。
  • 变更可控:变更走审批,自动生成版本快照,方便追溯。
  • 联动其他模块:进度、采购、质量、成本都能以节点为最小单元联动。
  • 风险降低:关键路径、里程碑可视化,提前发现瓶颈。

常见痛点(现实场景):Excel 没版本、多人协作冲突,变更口头传达、回溯困难;任务边界模糊导致现场做法不统一。目标是把这些痛点系统化治理。


二、WBS在工程项目部管理系统的位置与边界

WBS 是“计划与执行”的中枢。它连接:

  • 项目总控(看板/里程碑)
  • 进度(甘特/日报/周报)
  • 人员/班组(排班/考勤/成本)
  • 采购/物资(由节点生成采购需求)
  • EHS(风险/隐患关联到节点) 边界:WBS 负责“分解、版本、审批、下发、变更管理”,财务结算/采购支付等由对口系统处理,但需提供 API 与事件(Event)联动。

三、功能清单(先做 MVP,再迭代)

MVP(必须先做):

  • 创建/编辑树形 WBS(无限层级,但建议 4–6 层为主)
  • 节点属性:编码、名称、描述、起止、工期、负责人、预算、里程碑标记、附件链接
  • 节点依赖(前置/后置)与关键路径计算
  • 版本/快照(发布即生成版本)与变更单(CR)审批
  • 导入(Excel)与导出(Excel / 甘特图)
  • 基本权限(项目级别角色:查看/编辑/审批)

迭代(后续加):

  • 自动排产(基于资源负载)
  • 甘特高级交互(拖拽、工期调整实时计算)
  • 与采购、物资、工资系统事件总线联动(异步)
  • 离线编辑/多人协作冲突合并

四、系统架构(简洁图示)

建议采用前后端分离、微服务或单体拆分模式:React 前端 + Node.js/Express(或 Python FastAPI)后端 + PostgreSQL + 对象存储(S3/MinIO)+ 消息队列(Redis/Bull 或 RabbitMQ)用于导出/通知等异步任务。

下面用 Mermaid 给出简化架构图(可直接在支持 Mermaid 的编辑器里渲染):

代码语言:txt
复制
flowchart LR
  subgraph UI
    A[React SPA] -->|REST/GraphQL| API
  end
  subgraph Backend
    API[API Server] --> DB[(PostgreSQL)]
    API --> FS[(S3/MinIO)]
    API --> MQ[(Redis/Bull / RabbitMQ)]
    API --> Auth[(Auth Service)]
  end
  subgraph Integration
    ERP[ERP/财务] ---|API| API
    EHS[EHS系统] ---|API| API
    Notice[企业微信/邮件] ---|Webhook| MQ
  end

部署建议:API 做无状态扩展,JWT + Redis session(若需要); 报表/导出/Excel 走队列,完成后把文件放对象存储并返回下载链接。


五、业务流程(关键步骤 & 流程图)

核心流程:WBS 草案 → 分解节点 → 提交审批 → 审批通过并发布 → 下发执行 → 进度回填 → 若变更则走变更审批 → 归档版本。

Mermaid 流程图:

代码语言:txt
复制
flowchart TD
  A[项目经理创建WBS草案] --> B{是否完成初步分解?}
  B -- 否 --> A
  B -- 是 --> C[提交审批]
  C --> D[项目总监审批]
  D -- 拒绝 --> E[退回修改]
  D -- 同意 --> F[发布并下发任务]
  F --> G[班组执行并回填进度]
  G --> H[质检/监理复核]
  H --> I[里程碑完成?]
  I -- 否 --> G
  I -- 是 --> J[进入下阶段/结项]
  G --> K[提出变更?]
  K --> L[变更评审(影响评估)]
  L --> M[批准/拒绝]
  M -- 批准 --> F
  M -- 拒绝 --> G

要点说明:

  • 提交审批要附影响评估(工期/成本/资源),系统自动算关键路径变化并展示差异。
  • 发布时生成版本快照,保证历史可回溯。
  • 执行端的日报/周报应带 node_id,便于自动更新节点实际进度。

六、数据模型与接口设计(重点给出 SQL 与 API 设计)

下面是最小且实用的表结构(PostgreSQL)——放到代码区可直接执行。

代码语言:txt
复制
-- 项目表
CREATE TABLE project (
  id SERIAL PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  start_date DATE,
  end_date DATE,
  created_at TIMESTAMP DEFAULT now()
);
-- WBS 节点(最小)
CREATE TABLE wbs_node (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id) ON DELETE CASCADE,
  parent_id BIGINT,
  code VARCHAR(100),
  name VARCHAR(255) NOT NULL,
  description TEXT,
  level INT,
  sort_order INT DEFAULT 0,
  planned_start DATE,
  planned_end DATE,
  duration INT, -- 天数
  actual_start DATE,
  actual_end DATE,
  responsible_user_id INT,
  budget_amount NUMERIC(14,2),
  is_milestone BOOLEAN DEFAULT FALSE,
  metadata JSONB,
  version INT DEFAULT 1,
  created_by INT,
  updated_by INT,
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
-- 依赖(前置依赖)
CREATE TABLE wbs_dependency (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id),
  node_id BIGINT REFERENCES wbs_node(id),
  depends_on_node_id BIGINT REFERENCES wbs_node(id),
  type VARCHAR(10) DEFAULT 'FS', -- FS/SS/FF/SF
  created_at TIMESTAMP DEFAULT now()
);
-- 版本快照
CREATE TABLE wbs_version (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id),
  version_no INT,
  created_by INT,
  notes TEXT,
  snapshot JSONB,
  created_at TIMESTAMP DEFAULT now()
);
-- 变更单
CREATE TABLE wbs_change_request (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id),
  node_id BIGINT REFERENCES wbs_node(id),
  requested_by INT,
  reason TEXT,
  impact JSONB,
  status VARCHAR(30) DEFAULT 'PENDING',
  approver_id INT,
  handle_notes TEXT,
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);

API 设计建议(示例路由):

  • GET /api/projects/{pid}/wbs/tree — 获取树(可选 version)
  • POST /api/projects/{pid}/wbs — 创建节点
  • PUT /api/projects/{pid}/wbs/{nodeId} — 更新节点
  • DELETE /api/projects/{pid}/wbs/{nodeId} — 删除节点(检查子节点)
  • POST /api/projects/{pid}/wbs/{nodeId}/dependency — 添加依赖
  • GET /api/projects/{pid}/wbs/critical-path — 计算并返回关键路径
  • POST /api/projects/{pid}/wbs/import — Excel 导入任务(异步)
  • GET /api/projects/{pid}/wbs/export — 导出(异步)

七、前端实现思路与核心组件

前端分两大视图:树视图(结构维护)+ 甘特视图(时间轴与依赖)。树视图是 MVP 的核心,可以先做树视图、编辑侧栏、导入导出入口,再接甘特。

技术栈推荐:React + React Query(数据缓存)+ Ant Design(快速 UI)+ dnd-kit(拖拽)或 react-beautiful-dnd(拖拽)。甘特可以先用现成库如 dhtmlx-gantt 或 frappe-gantt。

下面给出最简 React 树组件(可复制运行,依赖最少)——完整代码会放在第 11 节。

(前端示例见第 11 节的整合代码区,以下是实现思路)

  • 请求 GET /api/projects/{pid}/wbs/tree 得到树形数据(后端返回 children 字段)。
  • 渲染递归节点,支持:添加子节点、编辑节点、删除(权限校验在按键处或后端检查)。
  • 编辑用 Modal(或侧边栏)实现,提交调用 POST/PUT 接口,保存后刷新树。
  • 节点拖拽(移动位置)可在后期加入 API POST /move,后端更新 parent_id 与 sort_order。

八、后端实现思路与关键逻辑(包含关键路径算法)

后端职责:CRUD、构建树、版本快照、关键路径计算、导入/导出任务调度、变更审批状态机。推荐用 Node.js + Express 或 FastAPI;数据库用 PostgreSQL(推荐)并用 JSONB 存不常用元数据。

关键路径(Critical Path)实现要点

  • 建图:节点为顶点,依赖为有向边(前置→后置)。
  • 环路检测:先做拓扑排序,若无法覆盖全部顶点则有环,返回错误提示(依赖错误)。
  • 最早开始(ES)与最晚开始(LS)计算:在拓扑序上按最长路径计算 ES;在反向拓扑上计算 LS。
  • 关键路径为 ES == LS 的节点集合。

下面我在第 11 节给出 Node.js 真实可跑的关键路径实现。


九、实战干货

这些是实操中常踩的坑,按重点列给你:

  1. 版本/快照:发布动作把当前树 JSON 存入 wbs_version,版本号自增。方便回退、审计。
  2. 并发更新:使用乐观锁(version 字段)或数据库事务;对关键字段更新做冲突检测并提示用户重新加载。
  3. 导入/导出异步:Excel 解析、甘特/PDF 导出放到后台队列(Bull + Redis),完成后上传到对象存储并告知用户下载链接。不要让 HTTP 请求长时间阻塞。
  4. 懒加载树:对于节点数很多的项目(几千级)启用按需加载子节点,避免一次性拉整个树。
  5. 关键路径缓存:关键路径计算可放到后台并缓存;只有在变更(节点时间/依赖变更)后重新计算。
  6. 权限模型:基于项目角色(ProjectRole)控制 CRUD/审批能力,节点级 ACL 仅在必要时使用(避免复杂度)。
  7. 审计日志:记录谁修改哪项字段、旧值与新值(建议做字段级 diff 存储)。
  8. 事件驱动集成:与采购/财务等系统用消息队列解耦(事件:WBS_NODE_PUBLISHED、WBS_NODE_CHANGED)。

十、上线验收与效果衡量(如何验收 MVP)

验收清单(务实版):

  • 功能完整性:能创建树、编辑节点、提交审批、发布并生成版本快照。
  • 关键路径:变更后关键路径计算正确(通过人工样例验证)。
  • 导入导出:Excel 导入能正确建立父子关系并带上关键字段。
  • 并发:多人同时编辑不同分支不冲突,冲突时有合理提示。
  • 权限:不同角色看到不同操作按钮并受后端校验。

KPI 建议:

  • 系统 WBS 覆盖率(上线后 3 个月采集)
  • 平均变更审批时间
  • 任务下发后首次回填时间(衡量传达效率)
  • 里程碑延迟天数统计(用于优化资源分配)

十一、整合代码参考(最小可跑 MVP)

下面把代码都放在一起:最小数据库建表、后端(Node.js + Express)含关键路径计算、前端(React 最简树视图 + 编辑 Modal)。这套代码适合快速验证业务流程并能扩展。

提示:把 SQL 在 PostgreSQL 中执行;Node.js 代码放到项目里并 npm install express pg;前端用 Create React App 或 Vite 创建后把组件放入。


A. 最小数据库(Postgres SQL)

代码语言:txt
复制
-- A.1 项目与最小 WBS 表
CREATE TABLE project (
  id SERIAL PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  start_date DATE,
  end_date DATE,
  created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE wbs_node (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id) ON DELETE CASCADE,
  parent_id BIGINT,
  code VARCHAR(100),
  name VARCHAR(255) NOT NULL,
  description TEXT,
  level INT,
  planned_start DATE,
  planned_end DATE,
  duration INT, -- 天
  responsible_user_id INT,
  is_milestone BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE wbs_dependency (
  id BIGSERIAL PRIMARY KEY,
  project_id INT REFERENCES project(id),
  node_id BIGINT REFERENCES wbs_node(id),
  depends_on_node_id BIGINT REFERENCES wbs_node(id),
  created_at TIMESTAMP DEFAULT now()
);

B. 后端:Node.js + Express(最小实现)

代码语言:txt
复制
app.js(Express 最小路由 + 关键路径)
// app.js
const express = require('express');
const db = require('./db');
const app = express();
app.use(express.json());
// 获取树(平表->树)
app.get('/api/projects/:pid/wbs/tree', async (req, res) => {
  const { pid } = req.params;
  const { rows } = await db.query('SELECT * FROM wbs_node WHERE project_id=$1 ORDER BY id', [pid]);
  const map = new Map();
  rows.forEach(r => map.set(r.id, { ...r, children: [] }));
  const roots = [];
  for (const node of map.values()) {
    if (node.parent_id && map.has(Number(node.parent_id))) {
      map.get(Number(node.parent_id)).children.push(node);
    } else {
      roots.push(node);
    }
  }
  res.json(roots);
});
// 创建节点
app.post('/api/projects/:pid/wbs', async (req, res) => {
  const { pid } = req.params;
  const { parent_id, code, name, planned_start, planned_end, duration, responsible_user_id, is_milestone } = req.body;
  const q = `INSERT INTO wbs_node(project_id,parent_id,code,name,planned_start,planned_end,duration,responsible_user_id,is_milestone)
             VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING *`;
  const { rows } = await db.query(q, [pid, parent_id || null, code || null, name, planned_start || null, planned_end || null, duration || null, responsible_user_id || null, is_milestone || false]);
  res.status(201).json(rows[0]);
});
// 添加依赖(前置)
app.post('/api/projects/:pid/wbs/:nodeId/dependency', async (req, res) => {
  const { pid, nodeId } = req.params;
  const { depends_on_node_id } = req.body;
  const q = `INSERT INTO wbs_dependency(project_id,node_id,depends_on_node_id) VALUES($1,$2,$3) RETURNING *`;
  const { rows } = await db.query(q, [pid, nodeId, depends_on_node_id]);
  res.status(201).json(rows[0]);
});
// 关键路径计算(最简):基于拓扑的最长路(假设无环)
app.get('/api/projects/:pid/wbs/critical-path', async (req, res) => {
  const { pid } = req.params;
  const nodesRes = await db.query('SELECT id,duration FROM wbs_node WHERE project_id=$1', [pid]);
  const depsRes = await db.query('SELECT node_id,depends_on_node_id FROM wbs_dependency WHERE project_id=$1', [pid]);
  const nodes = nodesRes.rows;
  const deps = depsRes.rows;
  const idToNode = new Map(nodes.map(n => [n.id, { ...n }]));
  const graph = new Map();
  const indeg = new Map();
  nodes.forEach(n => { graph.set(n.id, []); indeg.set(n.id, 0); });
  deps.forEach(d => {
    // edge depends_on_node_id -> node_id
    if (graph.has(d.depends_on_node_id)) {
      graph.get(d.depends_on_node_id).push(d.node_id);
      indeg.set(d.node_id, (indeg.get(d.node_id) || 0) + 1);
    }
  });
  // topo & ES
  const q = [];
  const ES = new Map();
  nodes.forEach(n => { ES.set(n.id, 0); if ((indeg.get(n.id) || 0) === 0) q.push(n.id); });
  const topo = [];
  while (q.length) {
    const u = q.shift(); topo.push(u);
    for (const v of (graph.get(u) || [])) {
      const durU = idToNode.get(u).duration || 0;
      const cand = ES.get(u) + durU;
      if (cand > (ES.get(v) || 0)) ES.set(v, cand);
      indeg.set(v, indeg.get(v) - 1);
      if (indeg.get(v) === 0) q.push(v);
    }
  }
  // 检查是否有环(若 topo 未覆盖所有节点)
  if (topo.length !== nodes.length) {
    return res.status(400).json({ error: '依赖存在环,请检查依赖关系' });
  }
  // 项目持续时间
  let projDur = 0;
  idToNode.forEach((n, id) => { projDur = Math.max(projDur, (ES.get(id) || 0) + (n.duration || 0)); });
  // 反向 LS
  const LS = new Map();
  idToNode.forEach((n, id) => LS.set(id, projDur - (n.duration || 0)));
  topo.reverse().forEach(u => {
    for (const v of (graph.get(u) || [])) {
      LS.set(u, Math.min(LS.get(u), (LS.get(v) || projDur) - (idToNode.get(u).duration || 0)));
    }
  });
  // 关键路径(ES==LS)
  const critical = [];
  idToNode.forEach((n, id) => {
    if ((ES.get(id) || 0) === (LS.get(id) || 0)) critical.push(id);
  });
  res.json({ projectDuration: projDur, ES: Object.fromEntries(ES), LS: Object.fromEntries(LS), critical });
});
app.listen(3000, () => console.log('WBS service listening on 3000'));

说明:关键路径实现是最简版,适合验证概念与小规模项目;生产环境需考虑依赖类型(FS/FF/SS/SF)、滞后/提前时间与更复杂的工期计算(工作日/节假日)。


C. 前端:React 最简树视图(可直接复制)

依赖很少:React 环境即可。

WbsTree.jsx

代码语言:txt
复制
// WbsTree.jsx
import React, { useState, useEffect } from 'react';
export default function WbsTree({ projectId }) {
  const [tree, setTree] = useState([]);
  const [editNode, setEditNode] = useState(null);
  const [showModal, setShowModal] = useState(false);
  useEffect(() => {
    fetchTree();
  }, [projectId]);
  async function fetchTree() {
    const res = await fetch(`/api/projects/${projectId}/wbs/tree`);
    const data = await res.json();
    setTree(data);
  }
  const handleAdd = (parentId = null) => { setEditNode({ parent_id: parentId }); setShowModal(true); };
  const handleEdit = (node) => { setEditNode(node); setShowModal(true); };
  const save = async (data) => {
    await fetch(`/api/projects/${projectId}/wbs`, {
      method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data)
    });
    setShowModal(false); setEditNode(null);
    fetchTree();
  };
  const renderNode = (n, lvl = 0) => (
    <div key={n.id || Math.random()} style={{ marginLeft: lvl * 12, padding: 8, borderLeft: '1px solid #eee' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <div>
          <strong>{n.name}</strong> {n.is_milestone && <span style={{ color: 'red' }}>[里程碑]</span>}
          <div style={{ fontSize: 12, color: '#666' }}>{n.planned_start || '-'} ~ {n.planned_end || '-'} • 负责: {n.responsible_user_id || '-'}</div>
        </div>
        <div>
          <button onClick={() => handleAdd(n.id)}>添加子节点</button>
          <button onClick={() => handleEdit(n)}>编辑</button>
        </div>
      </div>
      {n.children && n.children.map(c => renderNode(c, lvl + 1))}
    </div>
  );
  return (
    <div>
      <button onClick={() => handleAdd(null)}>新增根节点</button>
      <div style={{ marginTop: 12 }}>{tree.map(n => renderNode(n))}</div>
      {showModal && <EditModal node={editNode} onClose={() => setShowModal(false)} onSave={save} />}
    </div>
  );
}
function EditModal({ node, onClose, onSave }) {
  const [form, setForm] = useState(node || {});
  useEffect(() => setForm(node || {}), [node]);
  return (
    <div style={{ position: 'fixed', left: 20, top: 20, background: '#fff', padding: 12, border: '1px solid #ccc', zIndex: 999 }}>
      <div>名称:<input value={form.name || ''} onChange={e => setForm({ ...form, name: e.target.value })} /></div>
      <div>开始:<input type="date" value={form.planned_start || ''} onChange={e => setForm({ ...form, planned_start: e.target.value })} /></div>
      <div>结束:<input type="date" value={form.planned_end || ''} onChange={e => setForm({ ...form, planned_end: e.target.value })} /></div>
      <div>工期(天):<input type="number" value={form.duration || ''} onChange={e => setForm({ ...form, duration: Number(e.target.value) })} /></div>
      <div style={{ marginTop: 8 }}>
        <button onClick={() => onSave(form)}>保存</button> <button onClick={onClose}>取消</button>
      </div>
    </div>
  );
}


十二、FAQ

问1:WBS 应该拆到第几层合适?

答:没有固定公式,但实务里推荐 4 到 6 层较为平衡。太少(比如只有项目-阶段两层)会让执行层拿不到可操作的任务细节,责任与验收标准不明确;太细(超过 6 层)又会带来大量管理成本与沟通开销。实际判断标准是:一个节点是否能够被单个班组/个人在短期内(几天到两周)独立完成并能被验收?如果不能,就继续拆分。系统上要允许灵活拆分,但通过模板、默认粒度和培训来统一团队习惯,避免有人把任务拆得过细或过粗。最终目标是“能落地执行并便于统计”。

问2:变更频繁怎么避免历史混乱?

答:变更不可避免,但要把变更制度化:每次对计划、工期、责任人、预算等关键字段的修改都应走变更单(Change Request)。变更单里要包含变更原因、影响评估(对工期、成本、里程碑的影响)和审批链。审批通过后系统把当前树生成一个新版本快照(snapshot),并把变更记录写入审计日志。对小幅度、现场的临时调整可以考虑“快速签收模式”但也必须记录基本信息。通过版本+变更单+审计日志,你可以在需要时回溯任意时间点的计划,做到既灵活又可控,避免口头变更带来的责任模糊与历史混乱。

问3:如何把 WBS 与采购/人员/财务系统联动?

答:核心原则是“事件驱动、以节点为最小业务单元”。在每个 WBS 节点上保留必要的接口字段(例如 requires_materials, estimated_cost, responsible_team_id, linked_contract_id)。当节点进入某个阶段(如“准备-采购”),系统发出事件(WBS_NODE_REQUIRE_PURCHASE),由消息队列派发到采购系统生成采购需求;人员计划同样可生成排班或考勤工单;财务可以在节点完成或按阶段结算时触发成本摊销事件。实现方式推荐用异步消息队列(Redis/Bull、RabbitMQ、Kafka),避免同步强依赖,提高系统容错和可扩展性。接口应约定清晰的数据契约(payload 字段),并做好幂等处理与重试策略。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、为什么要把WBS做成系统板块
  • 二、WBS在工程项目部管理系统的位置与边界
  • 三、功能清单(先做 MVP,再迭代)
  • 四、系统架构(简洁图示)
  • 五、业务流程(关键步骤 & 流程图)
  • 六、数据模型与接口设计(重点给出 SQL 与 API 设计)
  • 七、前端实现思路与核心组件
  • 八、后端实现思路与关键逻辑(包含关键路径算法)
    • 关键路径(Critical Path)实现要点
  • 九、实战干货
  • 十、上线验收与效果衡量(如何验收 MVP)
  • 十一、整合代码参考(最小可跑 MVP)
    • A. 最小数据库(Postgres SQL)
    • B. 后端:Node.js + Express(最小实现)
    • C. 前端:React 最简树视图(可直接复制)
  • 十二、FAQ
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档