198 lines
8.2 KiB
Python
Executable File
198 lines
8.2 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():
|
|
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 |