fix: 修复app.py中的缩进错误和logger配置问题
This commit is contained in:
141
src/web/app.py
141
src/web/app.py
@@ -10,6 +10,9 @@ import os
|
||||
import json
|
||||
import logging
|
||||
import pandas as pd
|
||||
|
||||
# 配置日志
|
||||
logger = logging.getLogger(__name__)
|
||||
from datetime import datetime, timedelta
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Font
|
||||
@@ -631,9 +634,9 @@ def get_workorders():
|
||||
priority_filter = request.args.get('priority')
|
||||
with db_manager.get_session() as session:
|
||||
q = session.query(WorkOrder)
|
||||
if status_filter and status_filter != 'all':
|
||||
if status_filter and status_filter != 'all':
|
||||
q = q.filter(WorkOrder.status == status_filter)
|
||||
if priority_filter and priority_filter != 'all':
|
||||
if priority_filter and priority_filter != 'all':
|
||||
q = q.filter(WorkOrder.priority == priority_filter)
|
||||
q = q.order_by(WorkOrder.created_at.desc())
|
||||
rows = q.all()
|
||||
@@ -877,80 +880,80 @@ def generate_db_analytics(days: int, dimension: str) -> dict:
|
||||
} for d in day_keys]
|
||||
|
||||
# 工单统计
|
||||
total = len(workorders)
|
||||
status_counts = Counter([wo.status for wo in workorders])
|
||||
category_counts = Counter([wo.category for wo in workorders])
|
||||
priority_counts = Counter([wo.priority for wo in workorders])
|
||||
resolved_count = status_counts.get('resolved', 0)
|
||||
total = len(workorders)
|
||||
status_counts = Counter([wo.status for wo in workorders])
|
||||
category_counts = Counter([wo.category for wo in workorders])
|
||||
priority_counts = Counter([wo.priority for wo in workorders])
|
||||
resolved_count = status_counts.get('resolved', 0)
|
||||
workorders_stats = {
|
||||
'total': total,
|
||||
'open': status_counts.get('open', 0),
|
||||
'in_progress': status_counts.get('in_progress', 0),
|
||||
'resolved': resolved_count,
|
||||
'closed': status_counts.get('closed', 0),
|
||||
'by_category': dict(category_counts),
|
||||
'by_priority': dict(priority_counts)
|
||||
}
|
||||
|
||||
# 满意度
|
||||
scores = []
|
||||
for wo in workorders:
|
||||
if wo.satisfaction_score not in (None, ''):
|
||||
try:
|
||||
score = float(wo.satisfaction_score)
|
||||
scores.append(score)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_satisfaction = round(sum(scores)/len(scores), 1) if scores else 0
|
||||
dist = Counter([str(int(round(s))) for s in scores]) if scores else {}
|
||||
satisfaction_stats = {
|
||||
'average': avg_satisfaction,
|
||||
'distribution': {k: int(v) for k, v in dist.items()}
|
||||
'total': total,
|
||||
'open': status_counts.get('open', 0),
|
||||
'in_progress': status_counts.get('in_progress', 0),
|
||||
'resolved': resolved_count,
|
||||
'closed': status_counts.get('closed', 0),
|
||||
'by_category': dict(category_counts),
|
||||
'by_priority': dict(priority_counts)
|
||||
}
|
||||
|
||||
# 预警统计
|
||||
level_counts = Counter([al.level for al in alerts])
|
||||
active_alerts = len([al for al in alerts if al.is_active])
|
||||
resolved_alerts = len([al for al in alerts if not al.is_active and al.resolved_at])
|
||||
alerts_stats = {
|
||||
'total': len(alerts),
|
||||
'active': active_alerts,
|
||||
'resolved': resolved_alerts,
|
||||
'by_level': {k: int(v) for k, v in level_counts.items()}
|
||||
}
|
||||
|
||||
# 性能指标(基于对话响应时间粗略估计)
|
||||
resp_times = []
|
||||
for c in conversations:
|
||||
if c.response_time not in (None, ''):
|
||||
try:
|
||||
resp_time = float(c.response_time)
|
||||
resp_times.append(resp_time)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_resp = round(sum(resp_times)/len(resp_times), 2) if resp_times else 0
|
||||
throughput = len(conversations) # 期间内的对话数量
|
||||
# 错误率:用严重预警比例粗估
|
||||
critical = level_counts.get('critical', 0)
|
||||
error_rate = round((critical / alerts_stats['total']) * 100, 2) if alerts_stats['total'] > 0 else 0
|
||||
# 满意度
|
||||
scores = []
|
||||
for wo in workorders:
|
||||
if wo.satisfaction_score not in (None, ''):
|
||||
try:
|
||||
score = float(wo.satisfaction_score)
|
||||
scores.append(score)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_satisfaction = round(sum(scores)/len(scores), 1) if scores else 0
|
||||
dist = Counter([str(int(round(s))) for s in scores]) if scores else {}
|
||||
satisfaction_stats = {
|
||||
'average': avg_satisfaction,
|
||||
'distribution': {k: int(v) for k, v in dist.items()}
|
||||
}
|
||||
|
||||
# 预警统计
|
||||
level_counts = Counter([al.level for al in alerts])
|
||||
active_alerts = len([al for al in alerts if al.is_active])
|
||||
resolved_alerts = len([al for al in alerts if not al.is_active and al.resolved_at])
|
||||
alerts_stats = {
|
||||
'total': len(alerts),
|
||||
'active': active_alerts,
|
||||
'resolved': resolved_alerts,
|
||||
'by_level': {k: int(v) for k, v in level_counts.items()}
|
||||
}
|
||||
|
||||
# 性能指标(基于对话响应时间粗略估计)
|
||||
resp_times = []
|
||||
for c in conversations:
|
||||
if c.response_time not in (None, ''):
|
||||
try:
|
||||
resp_time = float(c.response_time)
|
||||
resp_times.append(resp_time)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
avg_resp = round(sum(resp_times)/len(resp_times), 2) if resp_times else 0
|
||||
throughput = len(conversations) # 期间内的对话数量
|
||||
# 错误率:用严重预警比例粗估
|
||||
critical = level_counts.get('critical', 0)
|
||||
error_rate = round((critical / alerts_stats['total']) * 100, 2) if alerts_stats['total'] > 0 else 0
|
||||
performance_stats = {
|
||||
'response_time': avg_resp,
|
||||
'uptime': 99.0, # 可接入真实监控后更新
|
||||
'error_rate': error_rate,
|
||||
'throughput': throughput
|
||||
'response_time': avg_resp,
|
||||
'uptime': 99.0, # 可接入真实监控后更新
|
||||
'error_rate': error_rate,
|
||||
'throughput': throughput
|
||||
}
|
||||
|
||||
return {
|
||||
'trend': trend,
|
||||
'trend': trend,
|
||||
'workorders': workorders_stats,
|
||||
'satisfaction': satisfaction_stats,
|
||||
'alerts': alerts_stats,
|
||||
'performance': performance_stats,
|
||||
'summary': {
|
||||
'total_workorders': total,
|
||||
'resolution_rate': round((resolved_count/total)*100, 1) if total > 0 else 0,
|
||||
'avg_satisfaction': avg_satisfaction,
|
||||
'active_alerts': active_alerts
|
||||
'total_workorders': total,
|
||||
'resolution_rate': round((resolved_count/total)*100, 1) if total > 0 else 0,
|
||||
'avg_satisfaction': avg_satisfaction,
|
||||
'active_alerts': active_alerts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1144,11 +1147,11 @@ def get_settings():
|
||||
settings['api_key'] = '******'
|
||||
settings['api_key_masked'] = True
|
||||
else:
|
||||
settings = {
|
||||
"api_timeout": 30,
|
||||
"max_history": 10,
|
||||
"refresh_interval": 10,
|
||||
"auto_monitoring": True,
|
||||
settings = {
|
||||
"api_timeout": 30,
|
||||
"max_history": 10,
|
||||
"refresh_interval": 10,
|
||||
"auto_monitoring": True,
|
||||
"agent_mode": True,
|
||||
# LLM与API配置(仅持久化,不直接热更新LLM客户端)
|
||||
"api_provider": "openai",
|
||||
|
||||
Reference in New Issue
Block a user