chore: initial import
This commit is contained in:
+487
@@ -0,0 +1,487 @@
|
||||
# 科技成果转化管理系统 — 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`
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user