53 KiB
53 KiB
基于Tauri的新闻文本分类系统 - 完整流程详解
本文档详细说明系统中所有模块的工作流程和交互细节
目录
1. 系统整体架构
1.1 架构分层图
graph TB
subgraph "客户端层 - Tauri Desktop"
Client[桌面客户端<br/>Tauri + Vue3]
end
subgraph "后端服务层 - Spring Boot"
API[API 网关]
Auth[认证模块<br/>Spring Security + JWT]
NewsSvc[新闻服务]
UserSvc[用户服务]
ClassifySvc[分类服务]
CrawlerSvc[爬虫服务]
StatisticsSvc[统计服务]
end
subgraph "数据存储层"
MySQL[(MySQL数据库)]
Redis[(Redis缓存)]
end
subgraph "机器学习模块"
ML[传统ML分类器<br/>朴素贝叶斯/SVM]
DL[深度学习分类器<br/>BERT<br/>可选]
Hybrid[混合分类器<br/>置信度融合]
end
Client -->|HTTP/WebSocket| API
API --> Auth
API --> NewsSvc
API --> UserSvc
API --> ClassifySvc
API --> CrawlerSvc
API --> StatisticsSvc
NewsSvc --> MySQL
NewsSvc --> Redis
UserSvc --> MySQL
UserSvc --> Redis
ClassifySvc --> ML
ClassifySvc --> DL
ClassifySvc --> Hybrid
CrawlerSvc -->|抓取新闻| ClassifySvc
CrawlerSvc -->|存储| MySQL
ML --> MySQL
DL --> MySQL
Hybrid --> MySQL
style Client fill:#e1f5ff
style API fill:#fff4e6
style MySQL fill:#f0f0f0
style Redis fill:#f0f0f0
style ML fill:#e8f5e9
style DL fill:#e8f5e9
style Hybrid fill:#e8f5e9
1.2 架构层次说明
| 层次 | 职责 | 技术实现 |
|---|---|---|
| 客户端层 | 用户界面、交互逻辑 | Tauri 2.x + Vue 3 + TypeScript |
| 网关层 | 统一入口、请求路由 | Spring MVC |
| 业务层 | 核心业务逻辑 | Spring Service |
| 数据层 | 数据持久化、缓存 | MyBatis-Plus + Redis |
| 算法层 | 文本分类算法 | Scikit-learn / Transformers |
1.3 客户端-后端交互
┌─────────────────────────────────────────────────────────────────────────────┐
│ 系统分层架构 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 客户端层 (Tauri Desktop) │ │
│ │ • 跨平台桌面应用 (Windows/macOS/Linux) │ │
│ │ • 使用系统WebView,体积小 (~50MB) │ │
│ │ • IPC通信: 前端 ↔ Rust安全通信 │ │
│ │ • 技术栈: Vue 3 + TypeScript + Tailwind CSS │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 后端服务层 (Spring Boot 3.x) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ API网关 │ │ 认证模块 │ │ 新闻服务 │ │ 分类服务 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 爬虫服务 │ │ 统计服务 │ │ 用户服务 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────┼──────────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ Elasticsearch│ │
│ │ • 用户数据 │ │ • 会话缓存 │ │ • 全文检索 │ │
│ │ • 新闻数据 │ │ • 热点数据 │ │ (可选) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
2. 用户登录认证流程
2.1 登录认证时序图
sequenceDiagram
participant C as 桌面客户端
participant API as 后端API
participant Auth as 认证模块
participant DB as MySQL数据库
participant Redis as Redis缓存
C->>API: POST /auth/login<br/>{username, password}
API->>Auth: 转发登录请求
Auth->>DB: 查询用户信息
DB-->>Auth: 返回用户数据
alt 用户存在且密码正确
Auth->>Auth: 验证通过<br/>生成JWT Token
Auth->>Redis: 缓存用户会话
Auth-->>API: 返回Token和用户信息
API-->>C: 200 OK<br/>{token, user}
C->>C: 存储Token到localStorage
else 用户不存在或密码错误
Auth-->>API: 401 Unauthorized
API-->>C: 登录失败
end
Note over C,Redis: 后续请求携带Token
C->>API: 请求其他接口<br/>Authorization: Bearer {token}
API->>Auth: 验证Token
Auth->>Redis: 检查Token有效性
Redis-->>Auth: Token有效
Auth-->>API: 验证通过
API-->>C: 返回请求数据
2.2 JWT认证机制
┌─────────────────────────────────────────────────────────────────────┐
│ JWT认证机制 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ JWT Token结构: │
│ ┌──────────────────┬──────────────────┬──────────────────┐ │
│ │ Header │ Payload │ Signature │ │
│ ├──────────────────┼──────────────────┼──────────────────┤ │
│ │ { │ { │ [签名部分] │ │
│ │ "alg": "HS256",│ "userId": 1, │ │ │
│ │ "typ": "JWT" │ "username": │ HMACSHA256( │ │
│ │ } │ "admin", │ base64UrlEncode│ │
│ │ │ "role": "ADMIN",│ (header) + │ │
│ │ │ "exp": 1234567890"." + base64UrlEncode│ │
│ │ │ } │ (payload), │ │
│ │ │ │ secret) │ │
│ └──────────────────┴──────────────────┴──────────────────┘ │
│ │
│ 密码加密: BCrypt (单向Hash,每次加密结果不同) │
│ • 工作因子: 10 (计算复杂度 2^10) │
│ • 存储格式: $2a$10$... │
│ │
│ Token存储策略: │
│ • 客户端: localStorage存储Token │
│ • 服务端: Redis缓存Token与用户映射 (24小时过期) │
│ • 请求头: Authorization: Bearer {token} │
│ │
└─────────────────────────────────────────────────────────────────────┘
2.3 RBAC权限模型
┌─────────────────────────────────────────────────────────────────────┐
│ RBAC权限模型 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 角色: │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ ADMIN │ │ USER │ │
│ │ • 所有权限 │ │ • 查看新闻 │ │
│ │ • 用户管理 │ │ • 搜索新闻 │ │
│ │ • 新闻管理 │ │ • 查看统计 │ │
│ │ • 分类管理 │ │ • 收藏新闻 │ │
│ │ • 系统配置 │ │ │ │
│ └────────────────┘ └────────────────┘ │
│ │
│ 权限注解 (Spring Security): │
│ • @PreAuthorize("hasRole('ADMIN')") // 需要管理员权限 │
│ • @PreAuthorize("hasAnyRole('ADMIN', 'USER')") // 用户或管理员 │
│ • @PreAuthorize("isAuthenticated()") // 需要登录 │
│ │
└─────────────────────────────────────────────────────────────────────┘
3. 新闻爬取与自动分类流程
3.1 爬虫与分类流程图
flowchart TD
Start([定时任务触发<br/>每30分钟]) --> Crawl[新闻爬虫模块]
Crawl -->|并行抓取| Source1[今日头条]
Crawl -->|并行抓取| Source2[腾讯新闻]
Crawl -->|并行抓取| Source3[新浪新闻]
Crawl -->|可配置| SourceN[其他新闻源...]
Source1 --> Clean1[数据清洗]
Source2 --> Clean2[数据清洗]
Source3 --> Clean3[数据清洗]
SourceN --> CleanN[数据清洗]
Clean1 --> Merge{合并数据}
Clean2 --> Merge
Clean3 --> Merge
CleanN --> Merge
Merge --> Dedup[去重处理]
Dedup --> Validate[数据验证]
Validate -->|标题和内容完整| Classify[文本分类服务]
Validate -->|数据不完整| Discard[丢弃]
Classify --> Hybrid{混合分类器}
Hybrid --> ML1[传统ML分类器<br/>关键词匹配]
Hybrid --> ML2[深度学习分类器<br/>BERT<br/>可选]
ML1 --> Confidence[置信度计算]
ML2 --> Confidence
Confidence --> Threshold{置信度 >= 0.75?}
Threshold -->|是| Success[分类成功]
Threshold -->|否| Default[使用默认分类<br/>科技类]
Success --> Save[保存到数据库]
Default --> Save
Save --> Cache[更新Redis缓存]
Cache --> End([流程结束])
Discard --> Log[记录日志]
Log --> End
style Start fill:#e3f2fd
style End fill:#e8f5e9
style Classify fill:#fff3e0
style Save fill:#f3e5f5
style Cache fill:#f3e5f5
3.2 文本分类详细流程
┌─────────────────────────────────────────────────────────────────────┐
│ 文本分类算法详细流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 输入: 标题 "华为发布新款折叠屏手机" │
│ 内容 "华为今天正式发布了新一代折叠屏手机,搭载最新麒麟芯片..." │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 文本预处理 │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ 1. 去除HTML标签、特殊字符 │ │ │
│ │ 2. 中文分词 (jieba) │ │ │
│ │ "华为 发布 新款 折叠屏 手机 ..." │ │ │
│ │ 3. 去除停用词 (的、了、是...) │ │ │
│ │ 4. 合并标题和内容: title + " " + content │ │ │
│ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 并行分类 (多线程) │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ 分类器1: 传统机器学习 (朴素贝叶斯) │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 1. TF-IDF特征提取 │ │ │
│ │ │ 向量化: [华为:0.5, 手机:0.3, 发布:0.2, ...] │ │ │
│ │ │ 2. 朴素贝叶斯预测 │ │ │
│ │ │ 3. 输出结果: TECHNOLOGY, 0.82 │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 分类器2: 关键词匹配 (规则引擎) │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 1. 关键词匹配统计 │ │ │
│ │ │ 科技类关键词: "科技", "手机", "华为", "芯片"... │ │ │
│ │ │ 匹配数: 5 │ │ │
│ │ │ 2. 输出结果: TECHNOLOGY, 0.50 │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 分类器3: 深度学习 BERT (可选) │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 1. 文本编码 (BERT Tokenizer) │ │ │
│ │ │ 2. 模型推理 │ │ │
│ │ │ 3. 输出结果: TECHNOLOGY, 0.88 │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 置信度融合 │ │
│ │ 结果比较: 选择最高置信度 0.88 (BERT) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 最终输出: │
│ { │
│ "categoryCode": "TECHNOLOGY", │
│ "categoryName": "科技", │
│ "confidence": 0.88, │
│ "classifierType": "HYBRID" │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.3 传统ML分类器原理
┌─────────────────────────────────────────────────────────────────────┐
│ 传统机器学习分类器工作原理 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 训练阶段: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 训练数据 (5000条标注新闻) │ │
│ │ ┌──────────┬──────────┬────────────┐ │ │
│ │ │ 标题 │ 内容 │ 分类标签 │ │ │
│ │ ├──────────┼──────────┼────────────┤ │ │
│ │ │华为手机 │华为发布...│ TECHNOLOGY │ │ │
│ │ │股市波动 │今日股市...│ FINANCE │ │ │
│ │ └──────────┴──────────┴────────────┘ │ │
│ │ │ │
│ │ ▼ │
│ │ TF-IDF向量化 │ │
│ │ • TF(t,d) = 词t在文档d中出现次数 / 文档d总词数 │ │
│ │ • IDF(t) = log(总文档数 / 包含词t的文档数) │ │
│ │ • TF-IDF = TF × IDF │ │
│ │ │ │
│ │ ▼ │
│ │ 朴素贝叶斯训练 │ │
│ │ • P(科技|向量) ∝ P(向量|科技) × P(科技) │ │
│ │ • 保存模型: vectorizer.pkl, classifier.pkl │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 预测阶段: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 新新闻: "iPhone 16 Pro Max评测" │ │
│ │ → 加载模型 → TF-IDF转换 → 朴素贝叶斯预测 → 返回分类结果 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
4. 新闻浏览与展示流程
4.1 浏览流程时序图
sequenceDiagram
participant U as 用户
participant C as 客户端
participant Cache as Redis缓存
participant API as 后端API
participant DB as MySQL数据库
participant ML as 分类服务
U->>C: 点击新闻列表
C->>Cache: 查询缓存
alt 缓存命中
Cache-->>C: 返回缓存数据
C-->>U: 展示新闻列表
else 缓存未命中
C->>API: GET /news/list<br/>?page=1&size=20
API->>DB: 分页查询新闻
DB-->>API: 返回新闻数据
API->>Cache: 写入缓存
Cache-->>API: 写入成功
API-->>C: 返回新闻列表
C-->>U: 展示新闻列表
end
U->>C: 点击某条新闻
C->>API: GET /news/{id}
API->>DB: 查询新闻详情
DB-->>API: 返回详情数据
API->>DB: 增加浏览量+1
API-->>C: 返回详情
C-->>U: 展示新闻详情
U->>C: 按分类筛选
C->>API: GET /news/category<br/>?categoryCode=TECHNOLOGY
API->>DB: 按分类查询
DB-->>API: 返回分类新闻
API-->>C: 返回结果
C-->>U: 展示分类新闻
U->>C: 搜索新闻
C->>API: GET /news/search<br/>?keyword=人工智能
API->>DB: 全文搜索
alt 使用Elasticsearch
API->>DB: ES搜索引擎
end
DB-->>API: 返回搜索结果
API-->>C: 返回结果
C-->>U: 展示搜索结果
4.2 缓存策略详解
┌─────────────────────────────────────────────────────────────────────┐
│ Cache-Aside缓存策略 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 读流程: │
│ 应用 ──查询──▶ Redis ──未命中──▶ MySQL ──返回──▶ 应用 ──写入──▶ Redis│
│ │ │
│ ▼ │
│ Redis ──命中──▶ 应用 │
│ │
│ 写流程: │
│ 应用 ──写入──▶ MySQL ──删除──▶ Redis │
│ │
│ 缓存Key设计: │
│ • 新闻列表: news:list:{page}:{size} │
│ • 分类新闻: news:category:{code}:{page}:{size} │
│ • 新闻详情: news:detail:{id} │
│ • 热门新闻: news:hot (5分钟更新) │
│ • 搜索结果: news:search:{keyword}:{page} (10分钟过期) │
│ │
└─────────────────────────────────────────────────────────────────────┘
5. 手动发布新闻与分类流程
5.1 发布流程图
flowchart TD
Start([管理员登录]) --> Verify{验证管理员权限}
Verify -->|权限不足| Deny[提示权限不足]
Verify -->|权限通过| Access[进入管理后台]
Access --> Click[点击发布新闻]
Click --> Form[填写新闻表单]
Form --> Input[输入标题、内容、<br/>选择分类、上传封面]
Input --> Option{是否自动分类?}
Option -->|是| AutoClassify[调用分类API]
Option -->|否| ManualClassify[手动选择分类]
AutoClassify --> ClassifySvc[文本分类服务]
ClassifySvc --> Hybrid{混合分类器}
Hybrid --> ML[传统ML分类]
Hybrid --> DL[深度学习分类<br/>可选]
ML --> Result[获取分类结果<br/>+ 置信度]
DL --> Result
Result --> ShowResult[显示推荐分类<br/>置信度: 0.85]
ShowResult --> Confirm{管理员确认?}
Confirm -->|修改| ManualClassify
Confirm -->|确认| Validate[验证数据]
ManualClassify --> Validate
Validate --> Check{数据是否完整?}
Check -->|否| Error[提示错误信息]
Check -->|是| Save[保存到数据库]
Save --> Status[状态: 已发布]
Status --> UpdateCache[更新Redis缓存]
UpdateCache --> Log[记录操作日志]
Log --> End([发布成功])
Error --> Form
Deny --> End
style Start fill:#e3f2fd
style End fill:#e8f5e9
style ClassifySvc fill:#fff3e0
style Save fill:#f3e5f5
style UpdateCache fill:#f3e5f5
5.2 发布表单示例
┌─────────────────────────────────────────────────────────────┐
│ 新闻发布表单 │
│ │
│ 标题: [iPhone 16 Pro Max深度评测________] │
│ │
│ 内容: [苹果最新旗舰iPhone 16 Pro Max震撼上市...] │
│ [搭载A18 Pro芯片,性能提升30%...] │
│ [影像系统全面升级...] │
│ │
│ 来源: [科技日报____] 作者: [张三____] │
│ │
│ 分类: [科技 ▼] 或 [🤖 自动分类] 置顶: [ ] 热门: [ ] │
│ │
│ 封面: [选择文件...] │
│ │
│ [🤖 自动分类] [💾 保存草稿] [✓ 立即发布] │
│ │
└─────────────────────────────────────────────────────────────┘
自动分类结果:
┌─────────────────────────────────────────────────────────────┐
│ 推荐分类: 科技 │
│ 置信度: ████████░░ 88% │
│ 分类器: 混合分类器 (BERT) │
│ [✓ 确认使用] [✏️ 修改选择] │
└─────────────────────────────────────────────────────────────┘
6. 数据可视化统计流程
6.1 统计数据流程图
flowchart LR
subgraph "数据采集"
DB[(MySQL数据库)]
Cache[(Redis缓存)]
end
subgraph "统计计算"
Count[分类统计]
Trend[趋势分析]
Hot[热门排行]
Accuracy[准确率分析]
end
subgraph "数据返回"
JSON[JSON数据]
end
subgraph "前端展示"
Pie[饼图<br/>分类分布]
Line[折线图<br/>发布趋势]
Bar[柱状图<br/>热门排行]
Gauge[仪表盘<br/>准确率]
end
DB --> Count
Cache --> Count
Count --> JSON
DB --> Trend
Trend --> JSON
DB --> Hot
Cache --> Hot
Hot --> JSON
DB --> Accuracy
Accuracy --> JSON
JSON --> Pie
JSON --> Line
JSON --> Bar
JSON --> Gauge
style DB fill:#f0f0f0
style Cache fill:#f0f0f0
style JSON fill:#e1f5ff
style Pie fill:#fff3e0
style Line fill:#fff3e0
style Bar fill:#fff3e0
style Gauge fill:#fff3e0
6.2 统计图表示例
┌─────────────────────────────────────────────────────────────┐
│ 统计仪表盘 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 10,523 │ │ 156 │ │ 85.2% │ │
│ │ 总新闻数 │ │ 今日新增 │ │ 分类准确率 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 分类分布 (饼图) 发布趋势 (折线图) │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ 时政 15% │ │ 200├─● │ │
│ │ ████████ │ │ 150├─ ●─● │ │
│ │ 财经 22% │ │ 100├─ ●─● │ │
│ │ ████████████ │ │ 50├─ ●─● │ │
│ │ 科技 18% │ │ 0└────────────────────▶ │ │
│ │ █████████ │ │ 12/18 12/19 12/20 │ │
│ └───────────────────┘ └───────────────────┘ │
│ │
│ 热门排行 (柱状图) │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ 浏览量 ││
│ │ 5000├─ █ ││
│ │ 4000├─ █ █ ││
│ │ 3000├─ █ █ █ ││
│ │ 2000├─ █ █ █ █ ││
│ │ 1000├─ █ █ █ █ █ ││
│ │ 0└────────────────────────────▶ ││
│ │ 新闻1 新闻2 新闻3 新闻4 新闻5 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────┘
7. 系统状态流转
7.1 用户状态机
stateDiagram-v2
[*] --> 未登录
未登录 --> 已登录: 登录成功
未登录 --> 未登录: 登录失败
已登录 --> 浏览新闻: 查看列表
浏览新闻 --> 已登录: 返回
已登录 --> 查看详情: 点击新闻
查看详情 --> 已登录: 返回
已登录 --> 搜索新闻: 输入关键词
搜索新闻 --> 已登录: 返回
已登录 --> 查看统计: 点击统计页
查看统计 --> 已登录: 返回
已登录 --> 管理员后台: 角色为ADMIN
管理员后台 --> 已登录: 返回
管理员后台 --> 发布新闻: 填写表单
发布新闻 --> 管理员后台: 发布成功
管理员后台 --> 管理分类: 分类管理
管理分类 --> 管理员后台: 返回
管理员后台 --> 管理用户: 用户管理
管理用户 --> 管理员后台: 返回
已登录 --> 未登录: 登出/Token过期
7.2 新闻状态流转
┌─────────────────────────────────────────────────────────────┐
│ 新闻状态流转 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────┐ 发布 ┌──────┐ 下架 ┌──────┐ │
│ │ 草稿 │─────────────▶│ 已发布│─────────────▶│ 已下架│ │
│ │ 0 │ │ 1 │ │ 2 │ │
│ └──────┘ └──────┘ └──────┘ │
│ │ ▲ │ │
│ │ │ │ │
│ └─────────────────────┴────────────────────┘ │
│ 重新发布/编辑 │
│ │
│ 状态说明: │
│ • 0 = 草稿: 编辑中,不对用户展示 │
│ • 1 = 已发布: 正常展示,可被搜索和浏览 │
│ • 2 = 已下架: 不展示,但保留数据 │
│ │
└─────────────────────────────────────────────────────────────┘
8. 文本分类算法决策流程
8.1 分类决策流程图
flowchart TD
Input[输入: 新闻标题 + 内容] --> Preprocess{文本预处理}
Preprocess --> Clean[去除HTML标签<br/>去除特殊字符<br/>统一编码]
Clean --> Segment[中文分词<br/>jieba]
Segment --> Parallel{并行分类}
Parallel --> Trad[传统ML分类器<br/>TF-IDF + 朴素贝叶斯]
Parallel --> Deep[深度学习分类器<br/>BERT<br/>可选]
Trad --> TradResult[结果1: 科技<br/>置信度: 0.82]
Deep --> DeepResult[结果2: 科技<br/>置信度: 0.88]
TradResult --> Compare[置信度比较]
DeepResult --> Compare
Compare --> Select{选择最高置信度}
Select --> CheckThreshold{置信度 >= 0.75?}
CheckThreshold -->|是| Return[返回分类结果<br/>科技, 0.88, HYBRID]
CheckThreshold -->|否| Default[返回默认分类<br/>科技, 0.50, HYBRID]
Return --> Output[输出分类结果]
Default --> Output
style Input fill:#e3f2fd
style Output fill:#e8f5e9
style Parallel fill:#fff3e0
style Compare fill:#f3e5f5
style Return fill:#c8e6c9
style Default fill:#ffccbc
8.2 分类器对比
| 分类器 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 传统ML | 训练快、资源少、易部署 | 准确率较低、需要特征工程 | 基础分类、快速上线 |
| 深度学习(BERT) | 准确率高、语义理解强 | 训练慢、资源消耗大 | 高精度要求场景 |
| 混合分类器 | 兼顾准确率和效率 | 配置复杂 | 生产环境推荐 |
9. 缓存更新策略
9.1 缓存流程图
flowchart TD
Request[请求到达] --> CheckCache{检查Redis缓存}
CheckCache -->|命中| Hit[返回缓存数据]
CheckCache -->|未命中| Miss[查询MySQL数据库]
Miss --> QueryDB[执行SQL查询]
QueryDB --> Result[获取查询结果]
Result --> WriteCache[写入Redis缓存]
WriteCache --> SetExpire[设置过期时间<br/>30分钟]
SetExpire --> Return[返回数据]
Hit --> Return
Return --> End[请求结束]
style CheckCache fill:#fff3e0
style WriteCache fill:#f3e5f5
style Hit fill:#c8e6c9
style Miss fill:#ffccbc
9.2 缓存过期策略
┌─────────────────────────────────────────────────────────────┐
│ 缓存过期策略 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 数据类型 过期时间 更新触发 │
│ ─────────────────────────────────────────────────────── │
│ 新闻列表 30分钟 自动过期 │
│ 分类新闻 30分钟 自动过期 │
│ 新闻详情 1小时 自动过期 │
│ 热门新闻 5分钟 定时任务更新 │
│ 统计数据 10分钟 定时任务更新 │
│ 用户会话 24小时 登录/登出 │
│ │
│ 主动失效场景: │
│ • 管理员发布新闻 → 清除列表缓存 │
│ • 管理员修改分类 → 清除分类缓存 │
│ • 管理员删除新闻 → 清除详情缓存 │
│ │
└─────────────────────────────────────────────────────────────┘
10. 新闻爬虫详细工作流程
10.1 爬虫工作流程图
flowchart TD
Trigger[定时任务触发<br/>Cron: 0 */30 * * * ?] --> Config{读取配置}
Config --> GetSources[获取启用的新闻源列表]
GetSources --> Loop{遍历每个新闻源}
Loop --> Fetch[发送HTTP请求]
Fetch --> CheckResp{响应状态码 200?}
CheckResp -->|否| ErrorLog[记录错误日志]
CheckResp -->|是| Parse[解析HTML<br/>Jsoup]
Parse --> Extract[提取新闻数据<br/>标题/内容/链接/时间]
Extract --> ValidateData{数据验证}
ValidateData -->|标题为空| ErrorLog
ValidateData -->|内容为空| ErrorLog
ValidateData -->|数据完整| Continue[继续处理]
Continue --> CheckDup{检查URL是否重复?}
CheckDup -->|已存在| Skip[跳过该新闻]
CheckDup -->|不存在| Process[处理新闻]
Process --> Classify[调用分类服务]
Classify --> SaveDB[保存到MySQL]
SaveDB --> UpdateCache[更新Redis缓存]
UpdateCache --> Next{还有新闻源?}
ErrorLog --> Next
Skip --> Next
Next -->|是| Loop
Next -->|否| Summary[生成爬取报告]
Summary --> Finish([任务结束])
style Trigger fill:#e3f2fd
style Finish fill:#e8f5e9
style Classify fill:#fff3e0
style SaveDB fill:#f3e5f5
style UpdateCache fill:#f3e5f5
10.2 爬虫配置示例
# 爬虫配置
crawler:
enabled: true
cron: "0 */30 * * * ?" # 每30分钟执行
user-agent: "Mozilla/5.0 ..."
timeout: 10000 # 10秒超时
sources:
- name: example
url: https://example.com/news
enabled: false
selector:
title: ".news-title"
content: ".news-content"
link: "a"
time: ".news-time"
- name: tech-news
url: https://tech-news.com
enabled: false
# ... 更多配置
总结
系统完整数据流
┌─────────────────────────────────────────────────────────────────────────┐
│ 系统完整数据流总览 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ 新闻爬取流程 │ │ 用户发布流程 │ │
│ │ • 定时任务 │ │ • 管理员操作 │ │
│ │ • 数据清洗 │ │ • 手动输入 │ │
│ │ • 去重验证 │ │ • 自动分类推荐│ │
│ └───────┬────────┘ └───────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 文本分类服务 │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │传统ML分类器│ │深度学习分类器│ │混合分类器 │ │ │
│ │ │朴素贝叶斯 │ │BERT │ │置信度融合 │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └──────────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ MySQL数据库 │ │
│ │ • news (新闻表) │ │
│ │ • sys_user (用户表) │ │
│ │ • news_category (分类表) │ │
│ │ • sys_log (日志表) │ │
│ └──────────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Redis缓存 │ │ 前端客户端展示 │ │
│ │ • 热点数据 │ │ • 新闻列表 │ │
│ │ • 会话数据 │ │ • 新闻详情 │ │
│ │ • 查询缓存 │ │ • 统计图表 │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ 用户交互流程: │
│ 用户登录 → 浏览新闻 → 搜索/筛选 → 查看详情 → 收藏新闻 → 查看统计 │
│ ▲ │ │
│ │ JWT Token │ │
│ └────────────────── 认证 ← Spring Security + JWT ─────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
关键技术点总结
| 模块 | 关键技术 | 说明 |
|---|---|---|
| 认证 | JWT + BCrypt | 无状态认证,密码安全加密 |
| 缓存 | Redis + Cache-Aside | 读写分离,过期策略 |
| 分类 | 朴素贝叶斯 + BERT | 传统ML与深度学习结合 |
| 爬虫 | Jsoup + HttpClient | 支持多源并行抓取 |
| API | RESTful + 统一响应 | 标准化接口设计 |
| 前端 | Vue 3 + Pinia | 组合式API,状态管理 |
文档版本: v1.0 更新日期: 2025-12-24 作者: 张俊恒