feat: 修复后端cors;增加前端自定义标题栏
This commit is contained in:
parent
8a455d95a0
commit
d4eaf9909d
|
|
@ -12,6 +12,12 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@EnableMethodSecurity
|
||||
|
|
@ -25,6 +31,7 @@ public class SecurityConfig {
|
|||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/v3/api-docs/**","/swagger-ui/**", "/swagger-ui.html").permitAll()
|
||||
|
|
@ -39,6 +46,21 @@ public class SecurityConfig {
|
|||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
configuration.setAllowedOriginPatterns(List.of("*"));
|
||||
configuration.setAllowedMethods(List.of("*"));
|
||||
configuration.setAllowedHeaders(List.of("*"));
|
||||
configuration.setAllowCredentials(true);
|
||||
configuration.setExposedHeaders(List.of("*"));
|
||||
configuration.setMaxAge(3600L);
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@
|
|||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-maximize",
|
||||
"core:window:allow-unmaximize",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-is-maximized",
|
||||
"core:window:allow-toggle-maximize",
|
||||
"opener:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
"minHeight": 500,
|
||||
"resizable": true,
|
||||
"fullscreen": false,
|
||||
"decorations": true,
|
||||
"decorations": false,
|
||||
"transparent": false,
|
||||
"alwaysOnTop": false,
|
||||
"center": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import TitleBar from '@/components/TitleBar.vue'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
|
|
@ -11,7 +12,10 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
<TitleBar />
|
||||
<div class="app-content">
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
|
@ -22,6 +26,12 @@ onMounted(() => {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
/* 应用内容区域 - 避免被自定义标题栏遮挡 */
|
||||
.app-content {
|
||||
height: 100%;
|
||||
padding-top: 40px; /* 标题栏高度 h-10 = 40px */
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { Minus, Square, Maximize2, X } from 'lucide-vue-next'
|
||||
|
||||
const appWindow = getCurrentWindow()
|
||||
const isMaximized = ref(false)
|
||||
const isDark = ref(false)
|
||||
|
||||
// 检查主题
|
||||
const checkTheme = () => {
|
||||
isDark.value = document.documentElement.classList.contains('dark')
|
||||
}
|
||||
|
||||
// 检查窗口是否最大化
|
||||
const checkMaximized = async () => {
|
||||
try {
|
||||
isMaximized.value = await appWindow.isMaximized()
|
||||
} catch (error) {
|
||||
console.error('Failed to check maximized state:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkMaximized()
|
||||
checkTheme()
|
||||
|
||||
// 监听主题变化
|
||||
const observer = new MutationObserver(() => {
|
||||
checkTheme()
|
||||
})
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
})
|
||||
})
|
||||
|
||||
// 最小化窗口
|
||||
const minimize = async () => {
|
||||
try {
|
||||
await appWindow.minimize()
|
||||
} catch (error) {
|
||||
console.error('Failed to minimize:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 最大化/还原窗口
|
||||
const toggleMaximize = async () => {
|
||||
try {
|
||||
await appWindow.toggleMaximize()
|
||||
await checkMaximized()
|
||||
} catch (error) {
|
||||
console.error('Failed to toggle maximize:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭窗口
|
||||
const close = async () => {
|
||||
try {
|
||||
await appWindow.close()
|
||||
} catch (error) {
|
||||
console.error('Failed to close:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- data-tauri-drag-region: Tauri 自动处理窗口拖拽 -->
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
class="titlebar h-10 flex items-center justify-between px-3 select-none fixed top-0 left-0 right-0 z-50"
|
||||
:class="{ 'titlebar-dark': isDark }"
|
||||
>
|
||||
<!-- 左侧:标题 -->
|
||||
<div data-tauri-drag-region class="flex items-center gap-2 pointer-events-none">
|
||||
<div class="titlebar-icon" :class="{ 'titlebar-icon-dark': isDark }" />
|
||||
<span class="titlebar-text">News Classifier</span>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:窗口控制按钮 -->
|
||||
<div class="flex items-center">
|
||||
<!-- 最小化按钮 -->
|
||||
<button
|
||||
@click="minimize"
|
||||
class="titlebar-btn"
|
||||
title="最小化"
|
||||
>
|
||||
<Minus :size="14" />
|
||||
</button>
|
||||
|
||||
<!-- 最大化/还原按钮 -->
|
||||
<button
|
||||
@click="toggleMaximize"
|
||||
class="titlebar-btn"
|
||||
:title="isMaximized ? '还原' : '最大化'"
|
||||
>
|
||||
<Square v-if="isMaximized" :size="12" />
|
||||
<Maximize2 v-else :size="14" />
|
||||
</button>
|
||||
|
||||
<!-- 关闭按钮 -->
|
||||
<button
|
||||
@click="close"
|
||||
class="titlebar-btn titlebar-btn-close"
|
||||
title="关闭"
|
||||
>
|
||||
<X :size="14" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.titlebar {
|
||||
background: hsl(var(--card));
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
}
|
||||
|
||||
.titlebar-dark {
|
||||
background: hsl(var(--sidebar));
|
||||
border-bottom: 1px solid hsl(var(--sidebar-border));
|
||||
}
|
||||
|
||||
.titlebar-icon {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: hsl(var(--primary));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.titlebar-icon-dark {
|
||||
background: hsl(var(--sidebar-primary));
|
||||
}
|
||||
|
||||
.titlebar-text {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
.titlebar-btn {
|
||||
padding: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: hsl(var(--muted-foreground));
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
}
|
||||
|
||||
.titlebar-btn:hover {
|
||||
background: hsl(var(--accent));
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
.titlebar-btn-close:hover {
|
||||
background: hsl(var(--destructive));
|
||||
color: hsl(var(--destructive-foreground));
|
||||
}
|
||||
|
||||
/* 防止拖拽时选中文本 */
|
||||
.titlebar * {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
</style>
|
||||
1665
docs/模块开发任务清单.md
1665
docs/模块开发任务清单.md
File diff suppressed because it is too large
Load Diff
494
docs/系统流程图.md
494
docs/系统流程图.md
|
|
@ -1,494 +0,0 @@
|
|||
# 基于Tauri的新闻文本分类系统 - 流程图
|
||||
|
||||
## 1. 系统整体架构图
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 2. 用户登录认证流程
|
||||
|
||||
```mermaid
|
||||
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: 返回请求数据
|
||||
```
|
||||
|
||||
## 3. 新闻爬取与自动分类流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 4. 新闻浏览与展示流程
|
||||
|
||||
```mermaid
|
||||
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: 展示搜索结果
|
||||
```
|
||||
|
||||
## 5. 手动发布新闻与分类流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 6. 数据可视化统计流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 7. 系统状态流转图
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 未登录
|
||||
|
||||
未登录 --> 已登录: 登录成功
|
||||
未登录 --> 未登录: 登录失败
|
||||
|
||||
已登录 --> 浏览新闻: 查看列表
|
||||
浏览新闻 --> 已登录: 返回
|
||||
|
||||
已登录 --> 查看详情: 点击新闻
|
||||
查看详情 --> 已登录: 返回
|
||||
|
||||
已登录 --> 搜索新闻: 输入关键词
|
||||
搜索新闻 --> 已登录: 返回
|
||||
|
||||
已登录 --> 查看统计: 点击统计页
|
||||
查看统计 --> 已登录: 返回
|
||||
|
||||
已登录 --> 管理员后台: 角色为ADMIN
|
||||
管理员后台 --> 已登录: 返回
|
||||
|
||||
管理员后台 --> 发布新闻: 填写表单
|
||||
发布新闻 --> 管理员后台: 发布成功
|
||||
|
||||
管理员后台 --> 管理分类: 分类管理
|
||||
管理分类 --> 管理员后台: 返回
|
||||
|
||||
管理员后台 --> 管理用户: 用户管理
|
||||
管理用户 --> 管理员后台: 返回
|
||||
|
||||
已登录 --> 未登录: 登出/Token过期
|
||||
```
|
||||
|
||||
## 8. 文本分类算法决策流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 9. 缓存更新策略流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
## 10. 新闻爬虫详细工作流程
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 流程图说明
|
||||
|
||||
### 关键模块交互说明
|
||||
|
||||
1. **客户端-后端交互**
|
||||
- 使用RESTful API进行通信
|
||||
- JWT Token进行身份认证
|
||||
- 响应格式统一: `{code, message, data, timestamp}`
|
||||
|
||||
2. **文本分类流程**
|
||||
- 支持传统机器学习(朴素贝叶斯/SVM)
|
||||
- 可选深度学习(BERT)
|
||||
- 混合分类器选择置信度最高的结果
|
||||
- 置信度低于阈值时使用默认分类
|
||||
|
||||
3. **缓存策略**
|
||||
- Redis缓存热点数据
|
||||
- 缓存过期时间: 30分钟
|
||||
- Cache-Aside模式
|
||||
|
||||
4. **数据流转**
|
||||
- 爬虫 → 分类 → 数据库 → 缓存 → 客户端
|
||||
- 管理员操作 → 数据库 → 缓存更新
|
||||
- 用户浏览 → 缓存/数据库 → 展示
|
||||
984
docs/系统流程详解.md
984
docs/系统流程详解.md
|
|
@ -1,984 +0,0 @@
|
|||
# 基于Tauri的新闻文本分类系统 - 完整流程详解
|
||||
|
||||
> 本文档详细说明系统中所有模块的工作流程和交互细节
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [系统整体架构](#1-系统整体架构)
|
||||
2. [用户登录认证流程](#2-用户登录认证流程)
|
||||
3. [新闻爬取与自动分类流程](#3-新闻爬取与自动分类流程)
|
||||
4. [新闻浏览与展示流程](#4-新闻浏览与展示流程)
|
||||
5. [手动发布新闻与分类流程](#5-手动发布新闻与分类流程)
|
||||
6. [数据可视化统计流程](#6-数据可视化统计流程)
|
||||
7. [系统状态流转](#7-系统状态流转)
|
||||
8. [文本分类算法决策流程](#8-文本分类算法决策流程)
|
||||
9. [缓存更新策略](#9-缓存更新策略)
|
||||
10. [新闻爬虫详细工作流程](#10-新闻爬虫详细工作流程)
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统整体架构
|
||||
|
||||
### 1.1 架构分层图
|
||||
|
||||
```mermaid
|
||||
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 登录认证时序图
|
||||
|
||||
```mermaid
|
||||
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 爬虫与分类流程图
|
||||
|
||||
```mermaid
|
||||
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 浏览流程时序图
|
||||
|
||||
```mermaid
|
||||
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 发布流程图
|
||||
|
||||
```mermaid
|
||||
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 统计数据流程图
|
||||
|
||||
```mermaid
|
||||
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 用户状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 未登录
|
||||
|
||||
未登录 --> 已登录: 登录成功
|
||||
未登录 --> 未登录: 登录失败
|
||||
|
||||
已登录 --> 浏览新闻: 查看列表
|
||||
浏览新闻 --> 已登录: 返回
|
||||
|
||||
已登录 --> 查看详情: 点击新闻
|
||||
查看详情 --> 已登录: 返回
|
||||
|
||||
已登录 --> 搜索新闻: 输入关键词
|
||||
搜索新闻 --> 已登录: 返回
|
||||
|
||||
已登录 --> 查看统计: 点击统计页
|
||||
查看统计 --> 已登录: 返回
|
||||
|
||||
已登录 --> 管理员后台: 角色为ADMIN
|
||||
管理员后台 --> 已登录: 返回
|
||||
|
||||
管理员后台 --> 发布新闻: 填写表单
|
||||
发布新闻 --> 管理员后台: 发布成功
|
||||
|
||||
管理员后台 --> 管理分类: 分类管理
|
||||
管理分类 --> 管理员后台: 返回
|
||||
|
||||
管理员后台 --> 管理用户: 用户管理
|
||||
管理用户 --> 管理员后台: 返回
|
||||
|
||||
已登录 --> 未登录: 登出/Token过期
|
||||
```
|
||||
|
||||
### 7.2 新闻状态流转
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 新闻状态流转 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────┐ 发布 ┌──────┐ 下架 ┌──────┐ │
|
||||
│ │ 草稿 │─────────────▶│ 已发布│─────────────▶│ 已下架│ │
|
||||
│ │ 0 │ │ 1 │ │ 2 │ │
|
||||
│ └──────┘ └──────┘ └──────┘ │
|
||||
│ │ ▲ │ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────────────┴────────────────────┘ │
|
||||
│ 重新发布/编辑 │
|
||||
│ │
|
||||
│ 状态说明: │
|
||||
│ • 0 = 草稿: 编辑中,不对用户展示 │
|
||||
│ • 1 = 已发布: 正常展示,可被搜索和浏览 │
|
||||
│ • 2 = 已下架: 不展示,但保留数据 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 文本分类算法决策流程
|
||||
|
||||
### 8.1 分类决策流程图
|
||||
|
||||
```mermaid
|
||||
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 缓存流程图
|
||||
|
||||
```mermaid
|
||||
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 爬虫工作流程图
|
||||
|
||||
```mermaid
|
||||
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 爬虫配置示例
|
||||
|
||||
```yaml
|
||||
# 爬虫配置
|
||||
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
|
||||
> 作者: 张俊恒
|
||||
Loading…
Reference in New Issue