Files
4an-workorder/app/views/dashboard.py
T
2025-08-08 10:38:10 +08:00

197 lines
8.1 KiB
Python
Executable File

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():
if current_user.role not in ['装维员', '统计员']:
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