Files
tech-achievement-management…/PPT_OUTLINE.md
T
2026-04-19 14:05:40 +08:00

488 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 科技成果转化管理系统 — 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 分钟)
- 12 页:每页 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`
```