from flask import render_template, flash, redirect, url_for from flask_login import login_required, current_user from scripts.models import db, Device, WorkOrder from collections import defaultdict from sqlalchemy import func from utils.db_utils import cache_query, db_operation def init_dashboard_routes(app): @app.route('/dashboard') @login_required def dashboard(): allowed_roles = ['装维员', '统计员', '管理员', 'admin'] if current_user.role not in allowed_roles and current_user.name != 'Admin': app.logger.warning(f'未授权访问:用户 {current_user.name} 尝试访问仪表盘页面') flash('您没有权限访问此页面') return redirect(url_for('login')) try: app.logger.info(f'用户 {current_user.name} 访问仪表盘页面') # 获取设备在线率数据 overall_stats = get_overall_device_stats() branch_stats = get_branch_device_stats() town_stats = get_town_device_stats() return render_template('dashboard.html', overall_stats=overall_stats, branch_stats=branch_stats, town_stats=town_stats) except Exception as e: app.logger.error(f"仪表盘页面加载失败: {str(e)}") flash('数据加载失败,请稍后重试') return redirect(url_for('login')) @cache_query(ttl=300) # 缓存5分钟 def get_overall_device_stats(): """获取总体设备在线率统计""" stats = {} # 获取设备类型列表 device_types = db.session.query(Device.device_type).distinct().all() device_types = [d[0] for d in device_types if d[0]] for device_type in device_types: # 获取该类型的设备总数 total_devices = db.session.query(func.count(Device.device_id))\ .filter(Device.device_type == device_type)\ .scalar() or 0 # 获取该类型的派单数 work_orders = db.session.query(func.count(WorkOrder.order_id))\ .join(Device, WorkOrder.device_id == Device.device_id)\ .filter(Device.device_type == device_type)\ .scalar() or 0 # 计算在线率 if total_devices > 0: online_rate = ((total_devices - work_orders) / total_devices) * 100 else: online_rate = 0 stats[device_type] = { 'total': total_devices, 'work_orders': work_orders, 'online_rate': round(online_rate, 2) } return stats @cache_query(ttl=300) # 缓存5分钟 def get_branch_device_stats(): """获取各支局设备在线率统计""" stats = {} # 获取所有支局 branches = db.session.query(Device.branch).distinct().all() branches = [b[0] for b in branches if b[0]] # 获取设备类型列表 device_types = db.session.query(Device.device_type).distinct().all() device_types = [d[0] for d in device_types if d[0]] for branch in branches: branch_stats = {} for device_type in device_types: # 获取该支局该类型的设备总数 total_devices = db.session.query(func.count(Device.device_id))\ .filter(Device.branch == branch, Device.device_type == device_type)\ .scalar() or 0 # 获取该支局该类型的派单数 work_orders = db.session.query(func.count(WorkOrder.order_id))\ .join(Device, WorkOrder.device_id == Device.device_id)\ .filter(Device.branch == branch, Device.device_type == device_type)\ .scalar() or 0 # 计算在线率 if total_devices > 0: online_rate = ((total_devices - work_orders) / total_devices) * 100 else: online_rate = 0 branch_stats[device_type] = { 'total': total_devices, 'work_orders': work_orders, 'online_rate': round(online_rate, 2) } # 计算该支局总体在线率 total_branch_devices = db.session.query(func.count(Device.device_id))\ .filter(Device.branch == branch)\ .scalar() or 0 total_branch_orders = db.session.query(func.count(WorkOrder.order_id))\ .join(Device, WorkOrder.device_id == Device.device_id)\ .filter(Device.branch == branch)\ .scalar() or 0 if total_branch_devices > 0: branch_online_rate = ((total_branch_devices - total_branch_orders) / total_branch_devices) * 100 else: branch_online_rate = 0 branch_stats['总计'] = { 'total': total_branch_devices, 'work_orders': total_branch_orders, 'online_rate': round(branch_online_rate, 2) } stats[branch] = branch_stats return stats @cache_query(ttl=300) # 缓存5分钟 def get_town_device_stats(): """获取各乡镇设备在线率统计""" stats = {} # 获取所有乡镇 towns = db.session.query(Device.town).distinct().all() towns = [t[0] for t in towns if t[0]] # 获取设备类型列表 device_types = db.session.query(Device.device_type).distinct().all() device_types = [d[0] for d in device_types if d[0]] for town in towns: town_stats = {} for device_type in device_types: # 获取该乡镇该类型的设备总数 total_devices = db.session.query(func.count(Device.device_id))\ .filter(Device.town == town, Device.device_type == device_type)\ .scalar() or 0 # 获取该乡镇该类型的派单数 work_orders = db.session.query(func.count(WorkOrder.order_id))\ .join(Device, WorkOrder.device_id == Device.device_id)\ .filter(Device.town == town, Device.device_type == device_type)\ .scalar() or 0 # 计算在线率 if total_devices > 0: online_rate = ((total_devices - work_orders) / total_devices) * 100 else: online_rate = 0 town_stats[device_type] = { 'total': total_devices, 'work_orders': work_orders, 'online_rate': round(online_rate, 2) } # 计算该乡镇总体在线率 total_town_devices = db.session.query(func.count(Device.device_id))\ .filter(Device.town == town)\ .scalar() or 0 total_town_orders = db.session.query(func.count(WorkOrder.order_id))\ .join(Device, WorkOrder.device_id == Device.device_id)\ .filter(Device.town == town)\ .scalar() or 0 if total_town_devices > 0: town_online_rate = ((total_town_devices - total_town_orders) / total_town_devices) * 100 else: town_online_rate = 0 town_stats['总计'] = { 'total': total_town_devices, 'work_orders': total_town_orders, 'online_rate': round(town_online_rate, 2) } stats[town] = town_stats return stats