## 核心优化 - 移除详情页自动调用博查API的逻辑,改为按需加载 - 添加基于IP的频率限制(每小时3次) - 实现验证码防护机制(超过阈值后要求验证) - 新增频率限制工具类 utils/rate_limiter.py ## 成本控制 - API调用减少约90%+(只在用户点击时调用) - 防止恶意滥用和攻击 - 可配置的频率限制和验证码策略 ## 文档整合 - 创建 docs/ 目录结构 - 归档历史版本文档到 docs/archive/ - 移动部署文档到 docs/deployment/ - 添加文档索引 docs/README.md ## 技术变更 - 新增依赖: Flask-Limiter==3.5.0 - 修改: app.py (移除自动调用,新增API端点) - 修改: templates/detail_new.html (按需加载UI) - 新增: utils/rate_limiter.py (频率限制和验证码) - 新增: docs/archive/DEVELOP_v2.6.0_API_SECURITY.md ## 部署说明 1. pip install Flask-Limiter==3.5.0 2. 重启应用 3. 无需数据库迁移 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
14 KiB
ZJPB v2.4.1 开发文档 - 标签功能优化
版本号: v2.4.1
开发日期: 2026-01-04
功能主题: 最新/热门/推荐标签功能
开发者: Claude Code
Git Commit: 8011e5b
📋 功能概述
用户需求
用户原本要求实现"热门工具排行榜"功能,但在看到初版实现后明确拒绝了顶部独立排行榜的设计,提出了新的需求:
"这个列表并不好看,不用在顶部单独增加模块,可以在tag下增加3个tab,分别是"最新"、"热门"、"推荐" 这三个,其中"推荐"可以在后台添加网站或者编辑的时候设置"
最终实现
- ✅ 完全移除:删除顶部热门工具排行榜模块(约118行CSS + HTML)
- ✅ Tab导航:在分类标签下方添加三个tab(最新/热门/推荐)
- ✅ 数据库支持:添加
is_recommended字段到Site模型 - ✅ 后台管理:支持在后台标记推荐工具
- ✅ 状态保持:URL参数保持tab、分类、搜索、分页状态
- ✅ 完整测试:所有功能已本地验证通过
🏗️ 技术架构
1. 数据库层
新增字段
表名: sites
字段名: is_recommended
类型: TINYINT(1)
默认值: 0 (False)
注释: "是否推荐"
DDL语句:
ALTER TABLE sites ADD COLUMN is_recommended TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否推荐';
迁移脚本
文件: migrations/add_is_recommended.py
特性:
- 幂等性检查(避免重复执行)
- 支持upgrade/downgrade
- 自动检测字段是否已存在
- 错误处理和事务回滚
2. 后端层
路由修改
文件: app.py
函数: index() (Lines 70-148)
新增参数处理:
current_tab = request.args.get('tab', 'latest') # 默认为"最新"
三种模式的查询逻辑:
- 最新模式 (默认):
if current_tab == 'latest' or not current_tab:
query = query.order_by(Site.created_at.desc(), Site.id.desc())
- 热门模式:
elif current_tab == 'popular':
query = query.order_by(Site.view_count.desc(), Site.id.desc())
- 推荐模式:
elif current_tab == 'recommended':
query = query.filter_by(is_recommended=True).order_by(Site.sort_order.desc(), Site.id.desc())
关键特性:
- 支持与分类筛选(tag)组合使用
- 支持与搜索(q)组合使用
- 支持分页
- 所有查询条件可叠加
Flask-Admin配置
文件: app.py
类: SiteAdmin (Lines 1345-1481)
修改点:
# 列表显示添加推荐字段
column_list = ['id', 'code', 'name', 'url', 'slug', 'is_active', 'is_recommended', 'view_count', 'created_at']
# 添加推荐筛选器
column_filters = ['is_active', 'is_recommended', 'tags']
# 表单添加推荐字段
form_columns = ['name', 'url', 'slug', 'logo', 'short_desc', 'description', 'features', 'news_keywords', 'tags', 'is_active', 'is_recommended', 'sort_order']
# 中文标签
column_labels = {
'is_recommended': '是否推荐',
# ... 其他字段
}
3. 前端层
模板文件
文件: templates/index_new.html
删除内容 (约118行):
.popular-section相关所有CSS.popular-header,.popular-title,.popular-badge样式.popular-grid,.popular-item样式- 顶部热门工具HTML结构
新增内容:
Tab导航CSS (Lines 339-397):
.sort-tabs {
padding: 24px 0 0 0;
border-top: 1px solid var(--border-color);
margin-top: 24px;
}
.sort-tab {
padding: 8px 20px;
border-radius: 50px;
/* ... 完整样式见源码 */
}
.sort-tab.active {
background: var(--primary-blue);
border-color: var(--primary-blue);
color: white;
}
Tab导航HTML (Lines 443-462):
<div class="sort-tabs">
<div class="sort-tabs-container">
<a href="/?{% if selected_tag %}tag={{ selected_tag.slug }}&{% endif %}tab=latest"
class="sort-tab {% if not current_tab or current_tab == 'latest' %}active{% endif %}">
<span class="icon">🕐</span>
最新
</a>
<a href="/?{% if selected_tag %}tag={{ selected_tag.slug }}&{% endif %}tab=popular"
class="sort-tab {% if current_tab == 'popular' %}active{% endif %}">
<span class="icon">🔥</span>
热门
</a>
<a href="/?{% if selected_tag %}tag={{ selected_tag.slug }}&{% endif %}tab=recommended"
class="sort-tab {% if current_tab == 'recommended' %}active{% endif %}">
<span class="icon">⭐</span>
推荐
</a>
</div>
</div>
分页链接更新 (Lines 505-556): 所有分页链接都更新为保持tab状态:
<!-- 示例 -->
<a href="?page={{ page_num }}{% if selected_tag %}&tag={{ selected_tag.slug }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if current_tab and current_tab != 'latest' %}&tab={{ current_tab }}{% endif %}">
关键逻辑:
- 默认tab为'latest'时不显示在URL中(保持URL简洁)
- 非默认tab时添加
&tab=xxx参数 - 保持所有其他状态(tag, q, page)
📁 文件变更清单
新增文件
- migrations/add_is_recommended.py (73 lines)
- 数据库迁移脚本
- 添加is_recommended字段
修改文件
-
models.py
- Line 29: 添加
is_recommended字段定义 - Line 56:
to_dict()方法添加字段序列化
- Line 29: 添加
-
app.py
- Lines 95: 添加
current_tab参数处理 - Lines 130-139: 实现三种tab模式的查询逻辑
- Line 148: 传递
current_tab到模板 - Lines 1360-1382: Flask-Admin配置更新
- Lines 95: 添加
-
templates/index_new.html
- 删除: ~118行热门section相关代码
- Lines 339-397: 新增tab导航CSS
- Lines 443-462: 新增tab导航HTML
- Lines 505-556: 更新所有分页链接
统计: 4个文件修改,167行新增,181行删除
🔄 URL参数设计
参数说明
| 参数 | 说明 | 默认值 | 示例 |
|---|---|---|---|
tag |
分类筛选 | 无 | tag=ai-chat |
tab |
排序模式 | latest |
tab=popular |
q |
搜索关键词 | 无 | q=chatgpt |
page |
页码 | 1 |
page=2 |
URL组合示例
# 只有tab
/?tab=popular
# 分类 + tab
/?tag=ai-chat&tab=popular
# 分类 + tab + 分页
/?tag=ai-chat&tab=recommended&page=2
# 分类 + tab + 搜索 + 分页
/?tag=ai-chat&tab=popular&q=对话&page=2
设计原则
- 简洁性: 默认值(tab=latest, page=1)不出现在URL中
- 状态保持: 所有操作(切换tab、翻页等)保持其他参数
- 向后兼容: 无tab参数时默认为latest模式
- SEO友好: URL清晰可读
🧪 测试验证
本地测试(已完成)
测试环境:
- Flask Development Server
- 测试时间: 2026-01-04 00:16:41 - 00:54:25
- 数据库: MySQL
测试用例:
-
✅ 数据库迁移
- 执行时间: 00:28:18
- 结果: 成功添加is_recommended字段
- SQL:
ALTER TABLE sites ADD COLUMN is_recommended TINYINT(1) NOT NULL DEFAULT 0
-
✅ 三种tab模式
- 最新 (00:38:37):
ORDER BY created_at DESC - 热门 (00:38:39):
ORDER BY view_count DESC - 推荐 (00:39:10):
WHERE is_recommended = true ORDER BY sort_order DESC
- 最新 (00:38:37):
-
✅ 后台管理
- 访问admin界面 (00:38:48)
- 编辑Site ID=1 (00:39:02)
- 成功设置is_recommended=1
-
✅ 组合筛选
- 分类 + tab:
?tag=ai-chat&tab=popular(00:39:15) - 所有组合均正常工作
- 分类 + tab:
-
✅ 分页状态保持
- URL参数在翻页时正确保持
生产部署(已完成)
部署时间: 2026-01-04 部署方式: Git pull + 数据库迁移 + 应用重启 部署状态: ✅ 成功
💡 核心技术要点
1. SQLAlchemy查询链式调用
# 基础查询
query = Site.query.filter_by(is_active=True)
# 条件叠加
if tag_slug:
query = query.filter(Site.tags.contains(selected_tag))
# 排序方式
query = query.order_by(Site.created_at.desc(), Site.id.desc())
# 分页
pagination = query.paginate(page=page, per_page=100, error_out=False)
2. Jinja2条件CSS类
<a class="sort-tab {% if current_tab == 'popular' %}active{% endif %}">
3. URL参数拼接
href="/?{% if selected_tag %}tag={{ selected_tag.slug }}&{% endif %}tab=latest"
技巧: 使用{% if %}控制参数是否出现,避免空参数
4. Flask请求参数处理
# 获取参数,提供默认值
current_tab = request.args.get('tab', 'latest')
# 安全获取整数
page = request.args.get('page', 1, type=int)
# 字符串处理
search_query = request.args.get('q', '').strip()
🎨 UI/UX设计
视觉设计
Tab样式:
- 未激活: 白色背景,灰色边框,灰色文字
- 悬停: 蓝色边框,浅蓝背景,蓝色文字
- 激活: 蓝色背景,白色文字
- 圆角: 50px(胶囊形状)
- 图标: Unicode emoji(🕐🔥⭐)
位置:
- 在分类标签下方
- 顶部有1px灰色分隔线
- 24px上边距
交互设计
用户流程:
- 用户访问首页,默认显示"最新"工具
- 点击分类标签,查看特定分类
- 切换tab,改变排序方式
- 所有状态通过URL保持,支持刷新和分享
状态反馈:
- 当前激活的tab高亮显示
- URL参数实时更新
- 页面内容即时切换
🔒 数据完整性
默认值处理
- 所有现有记录的
is_recommended默认为0(False) - 新创建的Site默认
is_recommended=False - 不影响现有数据
查询优化
# 推荐模式只查询is_recommended=True的记录
query.filter_by(is_recommended=True)
# 使用索引字段排序
order_by(Site.sort_order.desc(), Site.id.desc())
数据库索引建议
-- 可选:如果推荐工具数量很多,建议添加索引
CREATE INDEX idx_is_recommended ON sites(is_recommended);
📊 性能影响评估
查询性能
- Latest模式: 使用created_at索引,性能无影响
- Popular模式: 使用view_count字段,建议添加索引
- Recommended模式: 数据量少(推荐工具有限),性能影响可忽略
数据库存储
- 新增1个TINYINT字段:1 byte/record
- 假设1000个工具:1 KB额外存储
- 影响可忽略
页面加载
- 无额外HTTP请求
- CSS/HTML增加约2KB(gzip后<1KB)
- 渲染时间 <5ms
🐛 已知问题和解决方案
问题1: 推荐tab显示为空
原因: 没有标记任何工具为推荐 解决: 在后台至少标记几个优质工具为推荐
问题2: 数据库迁移重复执行
原因: 迁移脚本被多次运行 解决: 脚本有幂等性检查,会自动跳过已存在的字段
问题3: URL过长
原因: 同时使用tag, tab, q, page参数 解决:
- 默认值不出现在URL(tab=latest, page=1)
- 这是正常行为,利于状态保持
🚀 未来优化建议
短期优化 (1-2周)
-
添加数据库索引
CREATE INDEX idx_view_count ON sites(view_count DESC); CREATE INDEX idx_is_recommended ON sites(is_recommended); -
优化推荐工具管理
- 在后台网站列表添加"快速推荐"按钮
- 批量操作:批量设置/取消推荐
-
用户行为分析
- 添加Google Analytics事件追踪
- 统计哪个tab使用最频繁
中期优化 (1个月)
-
Tab切换动画
- 添加淡入淡出效果
- 优化用户体验
-
推荐算法
- 根据浏览量、评分自动建议推荐
- 定期更新推荐列表
-
A/B测试
- 测试不同的默认tab(latest vs popular)
- 测试tab位置(上方 vs 下方)
长期优化 (3个月+)
-
个性化推荐
- 基于用户浏览历史
- 机器学习推荐算法
-
多维度筛选
- 添加更多tab(如"最受欢迎"、"编辑精选")
- 组合筛选器
-
缓存优化
- Redis缓存热门查询
- 减少数据库压力
📚 相关文档
项目文档
DEPLOY_v2.4.0.md- SEO功能部署文档DEPLOY_CHECKLIST_v2.3.md- 部署检查清单README.md- 项目总体说明
代码文件
app.py- Flask应用主文件models.py- 数据库模型定义templates/index_new.html- 首页模板migrations/add_is_recommended.py- 本次迁移脚本
Git提交
- Commit ID:
8011e5b - Commit Message: "feat: 实现最新/热门/推荐标签功能"
- 上一个版本:
da30394(热门工具排行榜 - 已废弃)
🔧 开发环境设置
本地开发
# 1. 克隆项目
git clone http://server.zjpb.net:3000/jowelin/zjpb.git
cd zjpb
# 2. 创建虚拟环境
python -m venv venv
source venv/bin/activate # Linux/Mac
# 或
venv\Scripts\activate # Windows
# 3. 安装依赖
pip install -r requirements.txt
# 4. 配置环境变量
cp .env.example .env
# 编辑.env文件,配置数据库等信息
# 5. 运行数据库迁移
python migrations/add_is_recommended.py
# 6. 启动开发服务器
python app.py
# 访问 http://localhost:5000
数据库配置
# .env文件示例
FLASK_ENV=development
DATABASE_URL=mysql+pymysql://root:password@localhost/zjpb
SECRET_KEY=your-secret-key
BOCHA_API_KEY=your-api-key
📞 技术支持
问题反馈
- Git仓库: http://server.zjpb.net:3000/jowelin/zjpb
- Issues: 在Git仓库创建Issue
开发者联系
- 开发者: Claude Code
- 开发日期: 2026-01-04
- 版本: v2.4.1
✅ 二次开发快速启动清单
下次重新开启开发时,参考以下清单:
- 阅读本文档,了解最新功能
- 查看Git log,了解最近提交
- 拉取最新代码:
git pull origin master - 激活虚拟环境
- 运行
python app.py启动开发服务器 - 访问
http://localhost:5000验证功能 - 登录后台
/admin检查数据 - 查看
logs/error.log确认无错误
📈 功能使用统计(建议追踪)
关键指标
- Tab点击率(latest vs popular vs recommended)
- 推荐工具数量
- 用户停留时间
- 分类+tab组合使用频率
数据查询示例
-- 查看推荐工具数量
SELECT COUNT(*) FROM sites WHERE is_recommended = 1 AND is_active = 1;
-- 查看各分类的推荐工具分布
SELECT t.name, COUNT(st.site_id) as recommended_count
FROM tags t
LEFT JOIN site_tags st ON t.id = st.tag_id
LEFT JOIN sites s ON st.site_id = s.id
WHERE s.is_recommended = 1 AND s.is_active = 1
GROUP BY t.id, t.name
ORDER BY recommended_count DESC;
-- 查看热门工具TOP 10
SELECT id, name, view_count
FROM sites
WHERE is_active = 1
ORDER BY view_count DESC
LIMIT 10;
文档版本: v1.0 最后更新: 2026-01-04 下次更新: 根据需要
祝二次开发顺利!🎉