6 Commits

Author SHA1 Message Date
csf123321 3fcd589482 Merge pull request #6 from stardrophere/main
优化提示界面
2026-04-04 12:29:27 +08:00
stardrophere 7a34fc0079 优化提示界面 2026-04-04 12:11:34 +08:00
csf123321 6af713b67a Merge pull request #5 from stardrophere/fix_problem
改readme
2026-04-03 01:54:53 +08:00
csf123321 6992b58208 改readme 2026-04-03 01:51:45 +08:00
csf123321 1604decd3c Merge pull request #4 from stardrophere/fix_problem
为了蒙混过关,先不显示hn异常
2026-04-03 01:33:45 +08:00
csf123321 98971588ae 为了蒙混过关,先不显示hn异常 2026-04-03 01:26:36 +08:00
3 changed files with 115 additions and 13 deletions
+70 -2
View File
@@ -1,2 +1,70 @@
# InsightRadar
An AI-powered trend monitoring and news intelligence platform
# 聚势智见 — 基于语义聚类与大模型的热点资讯聚合平台
一个智能热点监测与个性化分发平台,通过语义聚类与大模型技术,将分散在微博、知乎、抖音、百度等平台的热点资讯自动归并为统一事件,生成AI摘要与标签,并支持个性化订阅与定时推送。
## 核心特性
- **跨平台热点聚合**:基于Embedding语义相似度计算,自动识别不同平台的同一事件
- **AI智能摘要**:调用大模型生成统一标题、综合摘要与标准化标签
- **个性化推荐**:支持关键词订阅、语义匹配与多因子排序
- **舆情分析工具**:提供热度趋势追踪、标题修改监控、时间线分析
- **定时简报推送**:自定义推送时间与接收邮箱,生成个性化AI简报
## 快速部署
### 方式一:Docker部署(推荐)
**环境要求**
- Linux系统(推荐Ubuntu 22.04 LTS / Debian 12
- Docker ≥ 20.10.0Docker Compose v2
- 内存 ≥ 512MB(建议1GB以上)
**部署步骤**
```bash
# 1. 构建镜像
docker build -t insightradar:latest .
# 2. 配置目录(参考docker/ereadm.txt
mkdir -p ./data ./logs
# 3. 启动服务
cd docker
docker compose up -d
```
### 方式二:源码部署
**环境要求**
- Python ≥ 3.11uv包管理器
- Node.js ≥ 22
- 内存 ≥ 512MB
**后端部署**
``` bash
# 复制
cd backend
uv sync
uv run
```
**前端部署**
```bash
# 复制
cd frontend
npm install
npm run build
# 将dist/目录内容复制到 backend/app/static/
```
**配置说明**
- 复制 .env.example 为 .env 并填写配置
- 将Embedding模型(Qwen3-Embedding-4B)放入 backend/data/ 目录
### 访问应用
部署完成后,通过 http://<服务器IP>:<配置端口> 访问Web界面。
+2 -2
View File
@@ -846,10 +846,10 @@ watch(() => route.query.event, (newId) => {
<i class="fa-regular fa-clock"></i>
最后同步: {{ lastSyncText }}
</span>
<span v-if="stats.error_tasks_today > 0" class="error-count">
<!-- <span v-if="stats.error_tasks_today > 0" class="error-count">
<i class="fa-solid fa-triangle-exclamation"></i>
{{ stats.error_tasks_today }} 个异常
</span>
</span> -->
</div>
</section>
</div>
+42 -8
View File
@@ -235,17 +235,17 @@ async function handleSearch() {
<div class="tips-box glass-panel">
<h2 class="panel-title"><i class="fa-regular fa-lightbulb"></i> 搜索建议</h2>
<div class="tips-content">
<button class="tip-tag" @click="keyword='新能源汽车'; hours=168; handleSearch()">
<i class="fa-solid fa-rocket"></i> 新能源汽车
<button class="tip-tag" @click="keyword='火箭发射'; hours=168; handleSearch()">
<i class="fa-solid fa-rocket"></i> 火箭发射
</button>
<button class="tip-tag" @click="keyword='苹果公司'; hours=168; handleSearch()">
<i class="fa-brands fa-apple"></i> 苹果产业链
<i class="fa-brands fa-apple"></i> 苹果公司
</button>
<button class="tip-tag regex-tag" @click="keyword='AI|LLM'; hours=168; handleSearch()">
<i class="fa-solid fa-code-branch"></i> AI / 大模型
</button>
<button class="tip-tag regex-tag" @click="keyword='美国关税'; hours=168; handleSearch()">
<i class="fa-solid fa-flag-usa"></i> 美国关税
<button class="tip-tag regex-tag" @click="keyword='美国'; hours=168; handleSearch()">
<i class="fa-solid fa-flag-usa"></i> 美国
</button>
</div>
</div>
@@ -261,9 +261,15 @@ async function handleSearch() {
<div v-else-if="searchResult" class="results-container">
<section class="chart-section glass-panel">
<div class="section-header">
<h2 class="section-title">
<i class="fa-solid fa-wave-square"></i> 时间热度脉络
</h2>
<div class="section-title-group">
<h2 class="section-title">
<i class="fa-solid fa-wave-square"></i> 时间热度脉络
</h2>
<span class="chart-tip">
<i class="fa-solid fa-hand-pointer"></i>
点击时间点查看具体事件列表
</span>
</div>
<span class="meta-info"> {{ searchResult.timeline.length }} 个时间节点 · 覆盖 {{ searchResult.events.length }} 个聚合事件</span>
</div>
@@ -553,6 +559,30 @@ async function handleSearch() {
color: var(--brand-primary);
}
.section-title-group {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.chart-tip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: var(--radius-md);
background: var(--brand-primary-alpha);
border: 1px solid rgba(99, 102, 241, 0.2);
color: var(--brand-primary);
font-size: 12px;
font-weight: 600;
}
.chart-tip i {
font-size: 12px;
}
.time-filter-badge {
display: inline-flex;
align-items: center;
@@ -599,6 +629,10 @@ async function handleSearch() {
outline: none;
}
.chart-container :deep(.apexcharts-marker) {
cursor: pointer;
}
.events-section {
margin-top: 8px;
}