# 科技成果转化管理系统 — PPT 提纲（草案）

> 用途：领导汇报型讲解 PPT，包含系统开发逻辑、开发历程、开发心得，并强调“小切口解决问题”的实践。包含安全专题与关键代码摘录。

---

## 0. 封面
- 项目名称：科技成果转化管理系统
- 汇报人 / 团队 / 日期

## 汇报时长与页数建议（30 分钟）
- 建议页数：18–22 页（含 2 张图：系统架构图 + 核心流程图）
- 时间分配：导入 2–3 分钟｜主体 22–24 分钟｜总结 3–4 分钟

## 30 分钟版（20 页）结构分配
- 业务与管理：8 页
- 技术与实现：12 页（含安全专题与代码亮点）

### 20 页目录建议（可直接用作 PPT 页标题）
1. 封面
2. 背景与目标（业务痛点 + 目标）
3. 业务价值与管理收益（闭环、合规、可追溯）
4. 系统开发逻辑（业务链路）
5. 核心流程图（从申报到归档）
6. 业务模块总览（功能地图）
7. 权限与角色体系（管理视角）
8. 统计分析与决策支持（管理视角）
9. 系统总体架构（技术总览）
10. 系统架构图（Nginx/Server/DB/文件）
11. 数据模型与权限策略（RBAC + 状态约束）
12. 上传与文件安全（白名单 + Magic Number）
13. 审计与日志体系（可追溯）
14. 认证与单点登录（JWT + token_version）
15. 接口防护与限流（分级限流 + 验证码）
16. 运维保障（磁盘监控 + 告警）
17. 开发历程（里程碑）
18. 小切口解决问题（工程细节）
19. 安全专题（集中总结）
20. 价值总结与下一步

### 页内时间建议（总计 30 分钟）
- 1–2 页：每页 1 分钟
- 3–8 页（业务/管理 6 页）：每页 1–1.5 分钟
- 9–16 页（技术 8 页）：每页 1.5–2 分钟
- 17–20 页（收束 4 页）：每页 1 分钟

---

# 20 页逐页内容（标题 + 关键点 + 口播稿 + 配图建议）

## 1. 封面
关键点
- 项目名称、汇报人、单位、日期
口播稿
- “今天汇报科技成果转化管理系统，重点讲业务闭环、管理价值与技术亮点。”
配图建议
- 项目 Logo 或简洁科技感背景图

## 2. 背景与目标
关键点
- 痛点：成果类型多、流程长、数据分散、统计难
- 目标：全生命周期管理，统一流程与口径
口播稿
- “核心目标是把成果从申报到归档形成标准化闭环，并保证数据口径一致。”
配图建议
- 痛点对比图或“问题→目标”对照图

## 3. 业务价值与管理收益
关键点
- 闭环流程：可控、可追溯
- 合规与审计：有据可查
- 统计可视化：辅助决策
口播稿
- “系统不仅解决业务效率，还能把过程做成可追溯的管理证据链。”
配图建议
- 价值三角图（效率/合规/决策）

## 4. 系统开发逻辑（业务链路）
关键点
- 申报→审核→统计→归档→运维
- 以业务路径驱动技术设计
口播稿
- “先确定业务主链路，再围绕关键节点补齐权限、安全与运维。”
配图建议
- 业务链路流程条

## 5. 核心流程图（从申报到归档）
关键点
- 查重拦截、审核分流、通过入库
- 统计分析与导出归档
口播稿
- “每个关键节点都定义了自动校验和权限控制，确保流程闭环。”
配图建议
- 使用下方 Mermaid 流程图渲染

## 6. 业务模块总览
关键点
- 账号权限、成果管理、审核、统计、导出、公告
- 模块之间的依赖关系
口播稿
- “业务模块围绕成果流转展开，管理侧在审核与统计两端发力。”
配图建议
- 功能模块矩阵或系统功能地图

## 7. 权限与角色体系（管理视角）
关键点
- RBAC 角色分级：普通/中级/高级/管理员/维护员/超管
- 关键场景：提交人与完成人权限分离、审核回避
口播稿
- “权限模型保证数据边界清晰，避免同人审核、越权查看。”
配图建议
- 角色金字塔或权限矩阵简图

## 8. 统计分析与决策支持
关键点
- 多维度统计（部门/年度/类型）
- 趋势图、雷达图、堆叠图
口播稿
- “统计不是展示数量，而是提供结构与趋势，支撑管理决策。”
配图建议
- 统计图示例（柱状/雷达/趋势）

## 9. 系统总体架构（技术总览）
关键点
- 前后端分离，RESTful API
- Nginx 统一入口，后端服务化
口播稿
- “技术架构选择以可扩展与可运维为优先。”
配图建议
- 架构分层示意图

## 10. 系统架构图（细化）
关键点
- SPA → Nginx → API → DB/文件
- 日志与审计并行
口播稿
- “数据流与文件流分开管理，方便安全控制与归档。”
配图建议
- 使用下方 Mermaid 架构图渲染

## 11. 数据模型与权限策略
关键点
- JSONB 处理完成人列表
- 状态驱动权限（pending/rejected/approved）
口播稿
- “用 JSONB 保证结构灵活，用状态机控制访问边界。”
配图建议
- 简化 ER 图或“状态×角色”矩阵

## 12. 上传与文件安全
关键点
- 扩展名白名单
- Magic Number 校验真实类型
- 下载强制 attachment
口播稿
- “文件安全是最大的攻击入口，因此做了三层防护。”
配图建议
- 三层防护示意图（白名单/校验/下载控制）

## 13. 审计与日志体系
关键点
- 全局审计日志拦截
- 语义化动作映射
- 入库可追溯
口播稿
- “任何关键操作都可追溯到人、时间与结果。”
配图建议
- 日志链路图或“审计追溯”示意

## 14. 认证与单点登录
关键点
- JWT + 过期控制
- token_version 实现强制下线
口播稿
- “不依赖复杂系统，用一个版本号实现单点登录与强制失效。”
配图建议
- Token 版本演进示意图

## 15. 接口防护与限流
关键点
- 全局限流 + 认证接口更严限流
- 验证码与短信验证机制
口播稿
- “对高风险入口进行更严格的限流，防暴力破解。”
配图建议
- “分级限流”示意图

## 16. 运维保障（监控告警）
关键点
- 磁盘空间监控
- 自动告警通知
口播稿
- “提前发现问题比处理事故更重要，系统自动告警避免资源耗尽。”
配图建议
- 监控告警流程图

## 17. 开发历程（里程碑）
关键点
- 需求澄清 → 权限模型 → 联调闭环 → 安全加固
口播稿
- “按关键链路推进，先保证主流程可用，再做安全与运维加固。”
配图建议
- 时间线图

## 18. 小切口解决问题
关键点
- token_version 单点登录
- URL 脱敏日志
- Magic Number 校验
- 磁盘告警
口播稿
- “这些小机制代价低，但显著降低了安全与运维风险。”
配图建议
- 四象限小结卡片

## 19. 安全专题（集中总结）
关键点
- 认证、密码、传输、接口、文件、日志六层防护
口播稿
- “安全不是单点技术，是全链路策略组合。”
配图建议
- 六层安全防护环

## 20. 价值总结与下一步
关键点
- 价值：闭环、合规、可追溯、可扩展
- 下一步：流程可配置、多租户、统计深化
口播稿
- “本期完成的是基础闭环，下一步聚焦可配置与更深的管理洞察。”
配图建议
- “现在/下一步”对比图

## 1. 项目背景与目标
- 业务痛点：成果类型多、流程长、数据分散、审查流程不统一、统计与归档难
- 目标：实现成果全生命周期管理（录入—审核—统计—归档/导出），保障合规与安全

## 2. 系统开发逻辑（从需求到架构）
- 业务逻辑主线：成果申报 → 审核流转 → 统计分析 → 归档导出 → 运维保障
- 技术逻辑主线：前后端分离 → API 标准化 → RBAC + 状态权限 → 审计与安全 → 可运维

## 3. 系统总体架构（概览）
- SPA 前端 + Node.js 后端 + PostgreSQL + Nginx
- 架构图（可引用文档中的 mermaid 图）
- 核心数据流：前端请求 → 反向代理 → API → DB/文件存储

## 3.1 系统架构图（素材）
用途：用于 PPT 的“总体架构”页，可直接粘贴成图或用 Mermaid 生成。

```mermaid
graph TD
    Client[Web 前端 SPA<br/>React] -->|HTTPS/JSON| Nginx[Nginx 反向代理]
    Nginx -->|Proxy Pass| Server[Node.js 后端 API]
    Nginx -->|Static Files| Uploads[文件存储 Uploads]
    Server -->|SQL| DB[(PostgreSQL)]
    Server -->|审计日志| Logs[日志系统/审计库]
```

讲解要点（口播要点）
- 前后端分离，接口统一，安全与运维可控
- 文件与数据库分层存储，方便归档与扩展
- Nginx 统一入口，支持 HTTPS 与静态资源托管

## 4. 业务模块拆解
- 账号与权限（注册/登录/角色/权限矩阵）
- 成果管理（10 种类型、动态表单、附件、查重机制）
- 审核管理（多角色分工、回避机制、状态约束）
- 统计分析（多维度图表、趋势与贡献）
- 归档与导出（CSV、ZIP、电子档案）
- 通知公告（富文本、附件、系统告警）

## 5. 核心数据与权限模型（亮点）
- 角色体系：user / intermediate_user / senior_user / admin / maintainer / super_admin
- 权限控制：RBAC + 成果状态细粒度限制（pending / rejected / approved）
- 关键场景：提交人 vs 完成人权限区分、管理员回避审查

## 6. 关键技术实现（亮点聚焦）
- 文件上传安全：白名单 + Magic Number 校验 + 下载强制 attachment
- 审计日志：全局拦截、语义化动作映射、入库审计
- 单点登录：JWT + token_version 控制同账号并发
- 运维守护：磁盘空间监控 + 自动告警
- 限流与防暴力：全局与认证接口分级限流

## 7. 开发历程（里程碑）
- 需求澄清 → 权限模型定稿
- 数据结构与接口标准 → 后端骨架
- 前后端联调 → 上传/审核/统计闭环
- 安全与运维加固 → 上线前合规检查

## 7.1 核心流程图（素材）
用途：用于 PPT 的“业务流程”页，可直接粘贴成图或用 Mermaid 生成。

```mermaid
flowchart LR
    A[用户登录/注册] --> B[成果申报]
    B --> C{查重拦截}
    C -- 通过 --> D[进入审核队列]
    C -- 重复/无效 --> B
    D --> E{审核结果}
    E -- 通过 --> F[入库统计/归档]
    E -- 驳回 --> B
    F --> G[统计分析]
    F --> H[导出/归档]
    G --> I[管理决策支持]
```

讲解要点（口播要点）
- 全流程闭环，关键节点有自动校验与权限控制
- 审核环节是质量门槛，统计与导出为管理输出

## 8. 开发过程中的关键抉择（为什么这样做）
- 为什么选择前后端分离：迭代快、职责清晰、部署灵活
- 为什么权限细分：保障科研数据边界与合规
- 为什么强调审计与日志：管理系统必须可追溯

## 9. 小切口解决问题（可讲的“工程细节”）
- Token 版本号：用最小改动实现“单点登录”和强制下线
- URL 脱敏日志：一行正则规避日志泄密风险
- Magic Number 校验：阻断伪装文件上载
- 磁盘空间监控：运维问题提前暴露，避免事故

## 10. 安全专题（单独章节）
- 身份认证：JWT + 过期控制 + token_version
- 密码安全：bcrypt 加盐哈希
- 传输安全：HTTPS + Nginx 反向代理
- 接口防护：Rate Limit + 验证码
- 数据与日志：敏感参数脱敏、审计日志入库
- 文件安全：白名单、Magic Number、下载强制 attachment

## 11. 开发心得（可复用的方法）
- 先稳定关键路径，再扩展边缘能力
- 面向“审计/合规”做系统设计，而不是事后补丁
- 把运维与安全作为功能的一部分
- 小机制大收益：用最小成本带来可见提升

## 12. 价值总结与下一步
- 业务价值：流程闭环、统计可视化、管理可追溯
- 技术价值：统一权限模型、安全与运维体系化
- 下一步（可选）：多租户、流程可配置、更多统计维度

---

# 关键代码摘录（可用作“技术亮点/安全章节”附页）

> 提示：以下代码块可直接截图进 PPT。路径已标注。

## A. 限流 + 移动端拦截 + 日志脱敏

路径：`server/index.js`

```js
morgan.token('safe-url', (req) => {
  let url = req.originalUrl || req.url;
  url = url.replace(/([?&])(token|password|code)=([^&]+)/gi, '$1$2=***');
  return url;
});

const globalLimiter = rateLimit({
  windowMs: 1 * 60 * 1000,
  max: 100,
  standardHeaders: true,
  legacyHeaders: false,
});

const authLimiter = rateLimit({
  windowMs: 1 * 60 * 1000,
  max: 10,
  standardHeaders: true,
  legacyHeaders: false,
});

app.use((req, res, next) => {
  const ua = req.headers['user-agent'] || '';
  const isMobile = /mobile|android|iphone|ipad|phone/i.test(ua);
  if (isMobile) return res.status(403).send('移动端访问被禁止');
  next();
});
```

## B. JWT 校验 + token_version 单点登录

路径：`server/middleware/auth.js`

```js
const token = req.headers['authorization']?.split(' ')[1] || req.query.token;
const decoded = jwt.verify(token, process.env.JWT_SECRET);

const tokenVersion = decoded.token_version || 0;
const result = await db.query('SELECT token_version FROM users WHERE id = $1', [decoded.id]);
const dbVersion = result.rows[0].token_version || 0;

if (tokenVersion !== dbVersion) {
  return res.status(401).json({ message: '账号在其他设备登录，请重新登录' });
}
```

## C. 密码加盐哈希（bcrypt）

路径：`server/routes/auth.js`

```js
const salt = await bcrypt.genSalt(10);
const passwordHash = await bcrypt.hash(newPassword, salt);

await db.query(
  'UPDATE users SET password_hash = $1, token_version = CASE WHEN token_version >= 2000000000 THEN 1 ELSE token_version + 1 END WHERE username = $2',
  [passwordHash, phoneNumber]
);
```

## D. 文件上传白名单 + Magic Number 校验

路径：`server/routes/achievements.js`

```js
const allowedExtensions = [
  '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
  '.txt', '.jpg', '.jpeg', '.png', '.zip', '.rar', '.7z'
];

const upload = multer({
  storage,
  fileFilter: (req, file, cb) => {
    const ext = path.extname(file.originalname).toLowerCase();
    if (allowedExtensions.includes(ext)) cb(null, true);
    else cb(new Error(`不支持的文件类型 (${ext})`));
  }
});

const fileType = await FileType.fromFile(file.path);
const allowedMimes = [
  'image/', 'application/pdf', 'application/msword',
  'application/vnd.openxmlformats-officedocument',
  'application/vnd.ms-excel', 'application/vnd.ms-powerpoint',
  'application/zip', 'application/x-zip-compressed',
  'application/x-rar-compressed', 'application/x-7z-compressed'
];

if (fileType && !allowedMimes.some(m => fileType.mime.startsWith(m))) {
  fs.unlinkSync(file.path);
  return res.status(400).json({ message: '文件真实类型不被允许' });
}
```

## E. 审计日志（语义映射 + 入库）

路径：`server/middleware/auditLogger.js`

```js
const getActionDescription = (method, url) => {
  if (path === '/api/auth/login' && method === 'POST') return '用户登录';
  if (path === '/api/achievements' && method === 'POST') return '上传成果';
  // ... 更多动作映射
};

const logMessage = `[AUDIT] IP:${clientIp} | User:${userInfo} | ${method} ${safeUrl} | Action:${description || 'Unknown'} | Status:${status} | Time:${duration}ms`;

await db.query(
  'INSERT INTO audit_logs (user_id, username, real_name, ip_address, method, url, description, status, duration) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)',
  [userId, username, realName, clientIp, method, safeUrl, description, status, duration]
);
```

## F. 运营级监控：磁盘空间告警

路径：`server/utils/diskMonitor.js`

```js
const THRESHOLD_BYTES = 10 * 1024 * 1024 * 1024; // 10GB

if (FreeSpace < THRESHOLD_BYTES) {
  const title = `【系统警告】磁盘空间不足(${root})`;
  const content = `剩余空间 ${freeGB} GB，低于阈值 10GB`;
  await db.query(
    'INSERT INTO notifications (title, content, publisher_id, publisher_name, is_top, created_at) VALUES ($1, $2, $3, $4, $5, CURRENT_TIMESTAMP)',
    [title, content, publisherId, '系统监控', true]
  );
}
```

---

## 附：引用的项目文档范围
- `PROJECT_DOCUMENTATION.md` 的“项目概述、权限体系、业务流程、技术架构、安全防御体系”章节
- 代码路径：`server/index.js`, `server/middleware/auth.js`, `server/middleware/auditLogger.js`, `server/routes/auth.js`, `server/routes/achievements.js`, `server/utils/diskMonitor.js`

```

