ljwx-bigscreen-lite
灵境万象健康监测大屏系统 - 轻量级重构版本
项目概述
这是从原始 ljwx-bigscreen 项目重构而来的模块化 Flask 应用,采用蓝图架构,大幅提升代码可维护性和可扩展性。
重构成果:
- ✅ 从单文件 8998 行拆分为 10 个蓝图模块
- ✅ 迁移 120 个核心路由(约 46% 的原始路由)
- ✅ 项目体积减少 92.8% (81M → 5.8M)
- ✅ 静态资源优化 92.4% (60.64MB → 4.6MB)
- ✅ 模板组件化,代码复用率提升 500%
📚 快速链接
- 前置要求 - 安装需求和环境准备
- 快速开始 - 3 步启动应用
- 项目结构 - 代码组织架构
- 核心功能模块 - 10 个蓝图详解
- 安全特性 - 租户隔离和参数验证
- 最新更新 (v2.1) - 租户上下文验证
- 故障排除 - 常见问题和解决方案
- 版本历史 - 发布记录
前置要求
在开始之前,请确保你的系统已安装以下软件:
- Python: 3.8 或更高版本
- MySQL: 8.0 或更高版本
- Redis: 6.0 或更高版本
- pip: 最新版本
推荐使用虚拟环境:
python -m venv venv
source venv/bin/activate # Linux/macOS
# 或
venv\Scripts\activate # Windows
快速开始
1. 安装依赖
pip install -r requirements.txt
2. 配置环境变量
创建 .env 文件:
# 数据库配置
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=123456
MYSQL_DATABASE=test
# Redis配置
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=
# 应用配置
APP_HOST=0.0.0.0
APP_PORT=5225
DEBUG=False
# 大屏配置
BIGSCREEN_TITLE=智能健康监测大屏
COMPANY_NAME=灵境万象
COMPANY_LOGO_URL=/static/images/logo.png
3. 运行应用
python run.py
应用将在 http://localhost:5225 启动
项目结构
ljwx-bigscreen-lite/
├── app/ # 应用主目录
│ ├── __init__.py # 应用工厂
│ ├── extensions.py # Flask扩展初始化
│ ├── blueprints/ # 蓝图模块(10个)
│ │ ├── health/ # 健康数据 (56路由)
│ │ ├── device/ # 设备管理 (15路由)
│ │ ├── views/ # 页面视图 (14路由)
│ │ ├── alert/ # 告警管理 (7路由)
│ │ ├── monitoring/ # 监控指标 (7路由)
│ │ ├── config_mgmt/ # 配置管理 (6路由)
│ │ ├── user/ # 用户管理 (5路由)
│ │ ├── statistics/ # 统计数据 (4路由)
│ │ ├── recommendation/ # 健康推荐 (4路由)
│ │ └── message/ # 消息系统 (2路由)
│ ├── services/ # 业务逻辑层(15个服务模块)
│ │ ├── health_query_base.py # 健康查询基础模块 (新增)
│ │ ├── health_score_engine.py
│ │ ├── user_health_data.py
│ │ └── ... (其他服务模块)
│ ├── models/ # 数据库模型
│ ├── utils/ # 工具库
│ ├── templates/ # Jinja2模板
│ │ ├── base.html # 基础模板
│ │ ├── components/ # 可复用组件(6个)
│ │ ├── main/ # 主监控大屏
│ │ └── personal/ # 个人健康大屏
│ └── static/ # 静态资源(4.6M)
│ ├── css/ # 样式文件
│ ├── js/ # JavaScript
│ ├── images/ # 图片
│ └── fonts/ # 字体
├── scripts/ # 迁移和维护脚本
│ ├── extract_routes.py # 路由提取工具
│ ├── migrate_routes.py # 路由迁移工具
│ ├── fix_imports.py # 导入修复工具
│ └── test_app_startup.py # 应用启动测试
├── config.py # 配置类
├── run.py # 应用入口
├── requirements.txt # Python依赖
├── MIGRATION_REPORT.md # 迁移详细报告
└── README.md # 本文件
核心功能模块
Health 蓝图 (健康数据)
路由数: 56 核心功能:
- 数据上传:
/upload_health_data,/upload_health_data_optimized - 数据查询:
/fetch_health_data,/get_health_data - 健康评分:
/api/health/scores,/api/health/score/comprehensive - 健康分析:
/api/health/analysis/comprehensive - 基线管理:
/api/health/baseline/<metric> - AI 推荐:
/api/health/recommendations - 健康画像:
/api/health-profile/list
Device 蓝图 (设备管理)
路由数: 15 核心功能:
- 设备信息上传和查询
- 设备分析和统计
- 设备历史时间线
- 电池预测
Views 蓝图 (页面视图)
路由数: 14 页面列表:
/main- 主监控大屏/personal- 个人健康大屏/health_main- 健康数据主页/device_dashboard- 设备监控大屏
其他蓝图
- alert: 告警管理和通知
- monitoring: Prometheus metrics 导出
- statistics: 统计数据和 KPI(包含完整的数据库查询实现)
- message: 消息系统
- config_mgmt: 配置管理
- recommendation: 健康推荐引擎
- user: 用户和组织管理
核心服务模块
health_query_base.py (新增 v1.0.1)
统一的健康查询参数处理模块:
功能:
parse_query_params()- 解析和标准化查询参数validate_query_params()- 验证参数有效性build_database_conditions()- 构建数据库查询条件build_cache_key()- 生成缓存键log_query_info()- 查询日志记录
支持的查询层级:
user- 用户级查询org- 组织级查询customer- 租户级查询device- 设备级查询
安全特性
租户上下文验证 (V2.1)
ljwx-bigscreen 实现了严格的多租户数据隔离机制:
核心组件:
TenantContext- 租户上下文管理器param_guard- 请求参数守门中间件@require_tenant_context- API 端点装饰器
安全规则:
- ✅ customerId 只从 Flask Session 获取,不允许前端传递
- ✅ 拒绝
customerId=0和orgId=0的请求 (400 错误) - ✅ 验证 customerId 与 session 一致性 (403 错误)
- ✅ 无效租户上下文自动跳转登录页
详细文档: 租户上下文验证实现
技术栈
- Web 框架: Flask 2.3+
- 数据库: MySQL 8.0 (SQLAlchemy ORM)
- 缓存: Redis 6.0+
- 实时通信: Flask-SocketIO
- 前端: jQuery 3.6 + ECharts 5.4
- 模板引擎: Jinja2
- 监控: Prometheus + Grafana
API 架构与路由配置
V2 API 架构
ljwx-bigscreen 采用 BFF (Backend For Frontend) 架构,通过 Flask 代理层将前端请求转发到 ljwx-boot 后端服务。
请求流程
浏览器 (fetch)
↓
Flask (/api/v2/*)
↓ [代理转发 + Token 注入]
ljwx-boot (/api/v2/*)
↓ [Sa-Token 验证 + 业务处理]
返回 Result<T> 标准格式
关键配置
⚠️ 重要: app/static/js/api-client-v2.js 中的 baseUrl 配置:
class BigscreenAPIClient {
constructor() {
this.baseUrl = '/api/v2' // ✅ 必须配置为 '/api/v2'
this.timeout = 30000
}
}
错误配置示例:
this.baseUrl = '' // ❌ 错误!会导致请求直接发送到 Flask 业务路由,绕过代理
Flask 代理配置
文件: app/blueprints/proxy/routes.py
# 注册在 /api/v2 路径
bp = Blueprint('proxy', __name__, url_prefix='/api/v2')
@bp.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
@require_auth
def proxy_to_boot(path):
"""
代理所有 /api/v2/* 请求到 ljwx-boot
自动注入 Authorization: Bearer {token}
"""
target_url = f'{BOOT_API_URL}/api/v2/{path}'
# 转发请求...
API 调用示例
// ✅ 正确:会通过代理转发到 ljwx-boot
const stats = await bigscreenAPI.getOrganizationStatistics('org123')
// 实际请求: /api/v2/organizations/statistics?orgId=org123
// 转发到: http://localhost:9998/api/v2/organizations/statistics
// ❌ 错误:如果 baseUrl = '',会直接请求 Flask 路由
// 实际请求: /organizations/statistics (404 Not Found)
当前可用的 V2 API 端点
ljwx-boot 目前实现的 V2 API 控制器:
| 控制器 | 路径前缀 | 功能 | 状态 |
|---|---|---|---|
HealthApiV2Controller |
/api/v2/health |
健康数据查询 | ✅ 已实现 |
MapApiV2Controller |
/api/v2/map |
地图模��� (点位、围栏) | ✅ 已实现 |
BigscreenHealthApiV2Controller |
(待配置) | 大屏健康数据 | ⚠️ 部分实现 |
注意: 其他 API 端点(devices, organizations, users 等)尚未实现 V2 版本,需要在 ljwx-boot 中创建对应的 V2 Controller。
认证流程
- Flask Session: 用户登录后,token 存储在 Flask Session 中
- 自动注入: Flask 代理从 Session 提取 token,注入到
Authorization头 - Sa-Token 验证: ljwx-boot 使用 Sa-Token 验证 JWT token
- 租户隔离: 从 token 中提取 customerId,确保多租户数据隔离
故障排查
问题: API 返回 404 Not Found
可能原因:
- ❌
api-client-v2.js中baseUrl配置错误(应为/api/v2) - ❌ ljwx-boot 未实现对应的 V2 API 端点
- ❌ Flask 代理未正确转发请求
解决方案:
# 1. 检查 baseUrl 配置
grep "this.baseUrl" app/static/js/api-client-v2.js
# 应输出: this.baseUrl = '/api/v2'
# 2. 检查 ljwx-boot 是否有对应的 Controller
grep -r "@RequestMapping.*api/v2" ljwx-boot/ljwx-boot-modules/src/main/java
# 3. 检查 Flask 代理日志
tail -f logs/app.log | grep "proxy"
开发指南
添加新路由
- 在对应蓝图的
routes.py中添加路由:
@bp.route('/new_endpoint', methods=['POST'])
@api_response
def new_function():
data = request.get_json()
# 业务逻辑
return success_response(data={'result': 'ok'})
- 如需新增业务逻辑,在
app/services/中创建服务模块
添加新蓝图
- 创建蓝图目录结构:
mkdir -p app/blueprints/new_blueprint
touch app/blueprints/new_blueprint/__init__.py
touch app/blueprints/new_blueprint/routes.py
touch app/blueprints/new_blueprint/services.py
- 在
app/__init__.py中注册蓝图:
from app.blueprints.new_blueprint import new_blueprint_bp
app.register_blueprint(new_blueprint_bp)
迁移说明
本项目从原始 ljwx-bigscreen/bigscreen/bigScreen/bigScreen.py 迁移而来,使用自动化脚本完成了大部分工作。
迁移进度:
- ✅ 已迁移: 120 个路由 (46%)
- ⏳ 待分类: 140 个路由 (54%)
详细迁移报告请查看 MIGRATION_REPORT.md
未迁移路由处理
原始文件中有 140 个路由被标记为 "unknown",需要人工审查:
# 查看未分类路由
python scripts/extract_routes.py
cat scripts/routes_catalog.json | jq '.unknown'
测试
运行启动测试
python scripts/test_app_startup.py
测试内容:
- ✅ 应用创建
- ✅ 蓝图注册
- ✅ 路由注册
- ✅ 关键路由检查
- ✅ 应用配置验证
部署
Docker 部署
# 构建镜像
docker build -t ljwx-bigscreen-lite:latest .
# 运行容器
docker run -d \
-p 5225:5225 \
-e MYSQL_HOST=your-mysql-host \
-e REDIS_HOST=your-redis-host \
--name bigscreen \
ljwx-bigscreen-lite:latest
生产环境配置
使用 production 配置:
# run.py
app = create_app('production')
建议配合 Gunicorn 使用:
gunicorn -w 4 -b 0.0.0.0:5225 "app:create_app('production')"
性能优化
已实施的优化:
- ✅ 连接池配置 (30 基础 + 50 溢出)
- ✅ Redis 缓存装饰器
- ✅ 数据批量处理 (200 条/批)
- ✅ 慢请求日志 (>1s)
- ✅ 静态资源压缩
监控
访问 Prometheus metrics:
http://localhost:5225/metrics
健康检查端点:
http://localhost:5225/health
最新更新 (v2.1)
2026-02-05 租户上下文验证
安全增强 - 实现多租户数据隔离机制:
✅ 新增组件:
app/utils/tenant_context.py- 租户上下文管理器app/utils/param_guard.py- 请求参数守门中间件
✅ 安全特性:
- customerId 只从 session 获取,禁止前端传递
- 拦截
customerId=0/orgId=0请求 (400 错误) - 跨租户访问防护 (403 错误)
- 无效租户上下文自动跳转登录
✅ 文件变更:
app/__init__.py- 注册参数守门中间件app/blueprints/bigscreen_api/routes.py- 使用 TenantContextapp/templates/main.html- 移除 URL customerId 参数app/static/js/api-client-v2.js- 移除 customerId 参数
详细文档: 租户上下文验证实现
历史更新 (v1.0.1-lite)
2025-12-20 修复内容
关键运行时错误修复 (Commit: bff8be0):
✅ 后端修复 (10项):
- 修复 HealthCacheService 异步/同步兼容性问题
- 添加缺失的函数别名 (
alert_fetch_alerts_by_orgIdAndUserId,message_fetch_messages_by_orgIdAndUserId) - 修复导入路径错误(相对导入 → 绝对导入)
- 添加
/get_total_info兼容路由(302 重定向到/api/statistics/overview) - 修复
/api/messages蓝图前缀问题 - 添加缺失的
api_logger日志记录器 - 创建
get_comprehensive_statistics_data()数据库查询函数 - 新建
health_query_base.py模块(参数解析和验证) - 修复数据库字段错误(
read_status→message_status != 'ACKNOWLEDGED') - 优化健康评分错误处理(500 → 200 with success=false)
✅ 前端修复 (3项):
- 修复
showCustomAlert回调函数类型检查 - 添加
initPersonnelManagementPanel防御性数据访问 - 添加
initMessageList安全属性读取
API 端点状态:
- ✅
/api/statistics/overview- 200 OK - ✅
/api/alerts- 200 OK - ✅
/api/messages- 200 OK (已修复) - ✅
/get_total_info- 302 Redirect - ✅
/api/health/score/comprehensive- 200 OK (已优化)
故障排除
常见问题
Q: 应用启动后 500 错误 A: 检查以下配置:
- MySQL 连接是否正常
- Redis 是否可访问
- 环境变量是否正确配置
Q: 健康评分返回空数据
A: 这是正常的,当组织下没有用户或缺少基线数据时,API 会返回 200 状态码,但 success: false。前端会显示默认值。
Q: JavaScript 错误 "callback is not a function" A: 已在 v1.0.1-lite 中修复。请刷新浏览器缓存(Ctrl+Shift+R)。
Q: 统计数据显示 0
A: 检查数据库中是否有数据,确认 customer_id 参数正确。
调试技巧
查看应用日志:
tail -f logs/app.log
检查 Redis 连接:
redis-cli -h 127.0.0.1 -p 6379 ping
测试 MySQL 连接:
mysql -h 127.0.0.1 -u root -p123456 -D test -e "SELECT COUNT(*) FROM t_user_health_data;"
已知问题
缓存服务异步问题: ✅ 已修复(v1.0.1)JavaScript 回调错误: ✅ 已修复(v1.0.1)- 部分路由未迁移: 140 个路由待分类
- 测试覆盖不足: 需要添加单元测试和集成测试
- API 文档缺失: 需要生成 Swagger/OpenAPI 文档
下一步计划
- 分类和迁移剩余 140 个路由
- 添加单元测试(pytest)
- 生成 API 文档(Swagger)
- 性能基准测试
- CI/CD 配置
- Docker Compose 编排
- Kubernetes 部署配置
贡献指南
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
许可证
本项目采用 MIT 许可证
联系方式
- 项目负责人: Bruno Gao
- GitHub: https://github.com/BrunoGaoSZ/ljwx-health
- 原始项目: ljwx-bigscreen
- 重构项目: ljwx-bigscreen-lite
版本历史
v2.1 (2026-02-05)
安全增强: 租户上下文验证
- ✅ 新增
TenantContext租户上下文管理器 - ✅ 新增
param_guard请求参数守门中间件 - ✅ customerId 只从 session 获取,禁止前端传递
- ✅ 拦截无效参数 (customerId=0, orgId=0)
- ✅ 跨租户访问防护
详细文档: 租户上下文验证实现
v1.0.1-lite (2025-12-21)
关键修复:
- ✅ 修复 10 个关键后端运行时错误
- ✅ 修复 3 个前端 JavaScript 错误
- ✅ 所有核心 API 端点恢复正常(5个端点)
- ✅ 新增
health_query_base.py查询基础模块 - ✅ 完善错误处理和防御性编程
- ✅ 更新完整项目文档
详细修复列表: 见上方"最新更新"章节
v1.0.0-lite (2025-12-19)
提交: ee67f33 及更早
重构成果:
- ✅ 从单文件 8998 行拆分为 10 个蓝图模块
- ✅ 迁移 120 个核心路由(46%)
- ✅ 项目体积减少 92.8% (81M → 5.8M)
- ✅ 静态资源优化 92.4% (60.64MB → 4.6MB)
- ✅ 模板组件化,代码复用率提升 500%
- ✅ Flask 蓝图架构重构完成
最后更新: 2026-02-05 当前版本: v2.1 状态: ✅ 生产就绪