release: v2.2.0 - 博查新闻搜索功能

新增功能:
- 集成博查Web Search API,自动获取网站相关新闻
- News模型添加source_name和source_icon字段
- 新闻管理后台界面优化
- 网站详情页新闻展示(标题、摘要、来源、链接)
- 定期任务脚本支持批量获取新闻
- 完整的API路由和测试脚本

技术实现:
- NewsSearcher工具类封装博查API
- 智能新闻搜索和去重机制
- 数据库迁移脚本migrate_news_fields.py
- API路由:/api/fetch-site-news 和 /api/fetch-all-news
- Cron任务脚本:fetch_news_cron.py

修改文件:
- config.py: 添加博查API配置
- models.py: News模型扩展
- app.py: 新闻获取路由和NewsAdmin优化
- templates/detail_new.html: 新闻展示UI

新增文件:
- utils/news_searcher.py (271行)
- migrate_news_fields.py (99行)
- fetch_news_cron.py (167行)
- test_news_feature.py (142行)
- NEWS_FEATURE_v2.2.md (408行)

统计:9个文件,1348行新增

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jowe
2025-12-30 22:04:35 +08:00
parent 00397a63b8
commit d7d21e19c9
9 changed files with 1348 additions and 8 deletions

99
migrate_news_fields.py Normal file
View File

@@ -0,0 +1,99 @@
"""
数据库迁移脚本 - 为News表添加source_name和source_icon字段
版本v2.2.0
日期2025-01-30
"""
import pymysql
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
def migrate():
"""执行数据库迁移"""
# 数据库配置
db_config = {
'host': os.environ.get('DB_HOST', 'localhost'),
'port': int(os.environ.get('DB_PORT', 3306)),
'user': os.environ.get('DB_USER', 'root'),
'password': os.environ.get('DB_PASSWORD', ''),
'database': os.environ.get('DB_NAME', 'ai_nav'),
'charset': 'utf8mb4'
}
try:
# 连接数据库
connection = pymysql.connect(**db_config)
cursor = connection.cursor()
print("=" * 60)
print("开始执行数据库迁移 v2.2.0")
print("=" * 60)
# 检查字段是否已存在
cursor.execute("""
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = %s
AND TABLE_NAME = 'news'
AND COLUMN_NAME IN ('source_name', 'source_icon')
""", (db_config['database'],))
existing_columns = [row[0] for row in cursor.fetchall()]
# 添加 source_name 字段
if 'source_name' not in existing_columns:
print("\n1. 添加 source_name 字段...")
cursor.execute("""
ALTER TABLE news
ADD COLUMN source_name VARCHAR(100)
COMMENT '新闻来源网站名称'
AFTER url
""")
print(">>> source_name 字段添加成功")
else:
print("\n1. source_name 字段已存在,跳过")
# 添加 source_icon 字段
if 'source_icon' not in existing_columns:
print("\n2. 添加 source_icon 字段...")
cursor.execute("""
ALTER TABLE news
ADD COLUMN source_icon VARCHAR(500)
COMMENT '新闻来源网站图标URL'
AFTER source_name
""")
print(">>> source_icon 字段添加成功")
else:
print("\n2. source_icon 字段已存在,跳过")
# 提交事务
connection.commit()
print("\n" + "=" * 60)
print(">>> 数据库迁移完成!")
print("=" * 60)
# 显示表结构
print("\n当前 news 表结构:")
cursor.execute("DESCRIBE news")
for row in cursor.fetchall():
print(f" - {row[0]}: {row[1]} {row[2]}")
except Exception as e:
print(f"\n>>> 迁移失败:{str(e)}")
if 'connection' in locals():
connection.rollback()
raise
finally:
if 'cursor' in locals():
cursor.close()
if 'connection' in locals():
connection.close()
print("\n数据库连接已关闭")
if __name__ == '__main__':
migrate()