新增查询指定日期范围和典型时段巡检路口数据的详情数据导出接口

This commit is contained in:
wangxu 2025-12-18 16:14:23 +08:00
parent 5d3c40988e
commit 73f3970319
3 changed files with 225 additions and 1 deletions

View File

@ -85,6 +85,12 @@ def cross_problems_detail_api():
def update_cross_examine_record_state_api(): def update_cross_examine_record_state_api():
return update_cross_examine_record_state(request.json) return update_cross_examine_record_state(request.json)
@app.route('/api/explode_cross_problem_detail', methods=['GET'])
def explode_cross_problem_detail_api():
return explode_cross_problem_detail(dict(request.args))
from app.user_views import * from app.user_views import *
from app.views_task import * from app.views_task import *
from app.views_workstation import * from app.views_workstation import *

View File

@ -450,3 +450,51 @@ def update_cross_examine_record_state(params):
return json.dumps(make_common_res(0, 'ok')) return json.dumps(make_common_res(0, 'ok'))
return json.dumps(make_common_res(11, '修改失败,请检查后重试')) return json.dumps(make_common_res(11, '修改失败,请检查后重试'))
# 离线导出巡检路口指标明细表
def explode_cross_problem_detail(params):
nodeid = check_param(params, 'nodeid')
if not nodeid:
return json.dumps(make_common_res(2, '缺少城市信息, 请刷新后重试'))
area_id = check_param(params, 'area_id')
if not area_id:
return json.dumps(make_common_res(3, '缺少辖区信息, 请刷新后重试'))
time_range = check_param(params, 'time_range')
if not time_range:
return json.dumps(make_common_res(4, '缺少时间范围信息, 请刷新后重试'))
start_date = check_param(params, 'start_date')
if not start_date:
return json.dumps(make_common_res(5, '缺少开始时间, 请选择开始时间'))
end_date = check_param(params, 'end_date')
if not end_date:
return json.dumps(make_common_res(6, '缺少结束时间, 请选择结束时间'))
excel = check_param(params, 'excel')
if not excel:
excel = 0
excel = int(excel)
routing_crosses = db_tmnet.query_routing_crosses(nodeid, area_id)
routing_crosses_dict = {item['crossid']: item for item in routing_crosses}
cross_roads_dir_dict = gen_crossids_roads_dir_dict_by_mysql([item['crossid'] for item in routing_crosses], nodeid)
for crossid in routing_crosses_dict.keys():
routing_crosses_dict[crossid]['roads_dir_dict'] = cross_roads_dir_dict[crossid]
tp_start = 't' + str(int(str(time_range.split('-')[0]).split(':')[0]) * 100 + int(str(time_range.split('-')[0]).split(':')[1]))
tp_end = int(str(time_range.split('-')[1]).split(':')[0]) * 100 + int(str(time_range.split('-')[1]).split(':')[1])
date_list = generate_date_range(start_date, end_date)
all_cross_data = []
for crossid in routing_crosses_dict.keys():
days_data = db_cross.query_cross_delay_info(crossid, nodeid, date_list, tp_start)
days_pb_list = parse_data2pb(days_data)
cross_data_list = parse_cross_delay_detail_list(routing_crosses_dict[crossid], days_pb_list, time_range)
all_cross_data.extend(cross_data_list)
if excel == 1:
return export_excel(all_cross_data)
res = make_common_res(0, 'ok')
res['data'] = all_cross_data
return json.dumps(clean_dict_nan(res, '-'), ensure_ascii=False)

View File

@ -14,6 +14,7 @@ import random
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import Alignment from openpyxl.styles import Alignment
from openpyxl.utils import get_column_letter
import proto.xlcomm_pb2 as pb import proto.xlcomm_pb2 as pb
from app.common_worker import * from app.common_worker import *
@ -2372,3 +2373,172 @@ def query_cross_delay_info_controller_export_excel(road_flow_delay_infos, road_f
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
as_attachment=True, as_attachment=True,
download_name=f"路口诊断指标.xlsx") download_name=f"路口诊断指标.xlsx")
def parse_cross_delay_detail_list(cross_info, delay_info_list, time_range):
cross_id = cross_info['crossid']
cross_name = cross_info['name']
weekday_str = '全周'
max_car_num = 0
for item in delay_info_list:
if item['data'].delay_info.car_num > max_car_num:
max_car_num = item['data'].delay_info.car_num
data_list = []
for item in delay_info_list:
relative_flow_rate = round(item['data'].delay_info.car_num / max_car_num, 2) if max_car_num > 0 else 0
item_dict = {
'cross_id': cross_id,
'cross_name': cross_name,
'weekday': weekday_str,
'time_range': time_range,
'day': item['day'],
'service_level': calc_service_level(item['data'].delay_info.delay_time, item['data'].delay_info.stop_times) if item['data'].delay_info.car_num >= 10 else '-',
'stop_times': round(item['data'].delay_info.stop_times, 2) if item['data'].delay_info.car_num >= 10 else '-',
'high_park_percent': item['data'].delay_info.high_park_percent if item['data'].delay_info.car_num >= 10 else '-',
'park_time': item['data'].delay_info.park_time if item['data'].delay_info.car_num >= 10 else '-',
'delay_time': item['data'].delay_info.delay_time if item['data'].delay_info.car_num >= 10 else '-',
'speed': round(item['data'].delay_info.speed / 100, 2) if item['data'].delay_info.car_num >= 10 else '-',
'move_speed': round(item['data'].delay_info.move_speed / 100, 2) if item['data'].delay_info.car_num >= 10 else '-',
'relative_flow_rate': relative_flow_rate if item['data'].delay_info.car_num >= 10 else '-',
'flow': item['data'].delay_info.car_num,
'jam_index': round(item['data'].delay_info.jam_index, 2) if item['data'].delay_info.car_num >= 10 else '-',
'imbalance_index': round(item['data'].delay_info.imbalance_index, 2) if item['data'].delay_info.car_num >= 10 else '-',
'service_level_color': 0,
'stop_times_color': 0,
'high_park_percent_color': 0,
'park_time_color': 0,
'delay_time_color': 0,
'speed_color': 0,
'move_speed_color': 0,
'relative_flow_rate_color': 0,
'flow_color': 0,
'jam_index_color': 0,
'imbalance_index_color': 0,
'stop_times_rate': 0,
'high_park_percent_rate': 0,
'park_time_rate': 0,
'delay_time_rate': 0,
'speed_rate': 0,
'move_speed_rate': 0,
'relative_flow_rate_rate': 0,
'flow_rate': 0,
'jam_index_rate': 0,
'imbalance_index_rate': 0,
}
data_list.append(item_dict)
for i in range(len(data_list)-1, -1, -1):
if i != 0:
item_data = data_list[i]
prev_data = data_list[i-1]
if item_data['service_level'] != '-' and prev_data['service_level'] != '-':
if item_data['service_level'] < prev_data['service_level']:
item_data['service_level_color'] = 2
elif item_data['service_level'] > prev_data['service_level']:
item_data['service_level_color'] = 1
for key in ('delay_time', 'stop_times', 'high_park_percent', 'park_time', 'relative_flow_rate', 'flow', 'jam_index', 'imbalance_index'):
if item_data[key] == '-' or prev_data[key] == '-':
continue
if prev_data[key] != 0:
rate = round((item_data[key] - prev_data[key]) / prev_data[key] * 100, 2)
item_data[key + '_rate'] = rate
if rate > 20:
item_data[key + '_color'] = 1
elif rate < -20:
item_data[key + '_color'] = 2
for key in ('speed', 'move_speed'):
if item_data[key] == '-' or prev_data[key] == '-':
continue
if prev_data[key] != 0:
rate = round((item_data[key] - prev_data[key]) / prev_data[key] * 100, 2)
item_data[key + '_rate'] = rate
if rate > 20:
item_data[key + '_color'] = 2
elif rate < -20:
item_data[key + '_color'] = 1
return data_list
def export_excel(all_cross_data):
wb = Workbook()
sheet1 = wb.active
table_header = [
{'A1': '路口ID'},
{'B1': '路口名称'},
{'C1': '运行日期'},
{'D1': '时段'},
{'E1': '停车次数'},
{'F1': '停车次数变化率'},
{'G1': '多次停车率%'},
{'H1': '多次停车率变化率'},
{'I1': '停车时间(秒)'},
{'J1': '停车时间变化率'},
{'K1': '延迟时间(秒)'},
{'L1': '延迟时间变化率'},
{'M1': '平均速度KM/H'},
{'N1': '平均速度变化率'},
{'O1': '不停车速度KM/H'},
{'P1': '不停车速度变化率'},
{'Q1': '相对流量'},
{'R1': '相对流量变化率'},
{'S1': '拥堵指数'},
{'T1': '拥堵指数变化率'},
{'U1': '路口失衡指数'},
{'V1': '路口失衡指数变化率'},
{'W1': '服务水平'},
{'X1': '服务水平变化情况'}
]
for item in table_header:
for k, v in item.items():
sheet1[k] = v
sheet1[k].alignment = Alignment(horizontal='center', vertical='center')
# 自动调整列宽
for col_idx, header in enumerate(table_header, 1):
# 计算列宽:可以根据字体大小适当调整这个公式
# 通常一个中文字符占2个单位宽度英文字符占1个单位宽度
column_width = len(list(header.values())[0].encode('utf-8')) * 1.2 # 粗略估算
adjusted_width = min(max(column_width, 10), 50) # 设置最小和最大宽度限制
sheet1.column_dimensions[get_column_letter(col_idx)].width = adjusted_width
for item in all_cross_data:
service_level_color = '-'
if item['service_level_color'] == 1:
service_level_color = '恶化'
elif item['service_level_color'] == 2:
service_level_color = '优化'
item_data = [
item['cross_id'],
item['cross_name'],
item['weekday'],
item['time_range'],
item['stop_times'],
item['stop_times_rate'],
item['high_park_percent'],
item['high_park_percent_rate'],
item['park_time'],
item['park_time_rate'],
item['delay_time'],
item['delay_time_rate'],
item['speed'],
item['speed_rate'],
item['move_speed'],
item['move_speed_rate'],
item['relative_flow_rate'],
item['relative_flow_rate_rate'],
item['jam_index'],
item['jam_index_rate'],
item['imbalance_index'],
item['imbalance_index_rate'],
item['service_level'],
service_level_color
]
sheet1.append(item_data)
file_stream = io.BytesIO()
wb.save(file_stream)
file_stream.seek(0) # 将指针移到文件开头
return send_file(
file_stream,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
as_attachment=True,
download_name=f"路口信息明细指标.xlsx")