diff --git a/app/cross_compare_report.py b/app/cross_compare_report.py index 0313a67..372d5e5 100644 --- a/app/cross_compare_report.py +++ b/app/cross_compare_report.py @@ -6,6 +6,7 @@ import os from app.cross_compare_common import * from app.report_common import * +from tool.compare_report import * from tool.qcos_func import get_client, CosFolderManager g_cos_root = 'https://xinglu-1324629296.cos.ap-beijing.myqcloud.com' g_cos_bucket = 'xinglu-1324629296' @@ -44,9 +45,11 @@ def gen_cross_compare_report(params): date_list = check_param(params, 'date_list') # 优化后 if not date_list or len(date_list) < 1: return json.dumps(make_common_res(7, '缺少日期参数,请最少选择一天作为查询日期')) + date_list = list(map(str, date_list)) compare_date_list = check_param(params, 'compare_date_list') # 优化前 if not compare_date_list or len(compare_date_list) < 1: return json.dumps(make_common_res(6, '缺少对比日期参数,请最少选择一天作为对比日期')) + compare_date_list = list(map(str, compare_date_list)) query_type = check_param(params, 'query_type') if not query_type: query_type = 0 @@ -74,7 +77,7 @@ def gen_cross_compare_report(params): return json.dumps(make_common_res(10, '查询路口信息失败')) cross_static_info, cross_ledger_info = gen_cross_static_info(crossid, nodeid, area_id, cross_ledger_info_dict) roads_dir_dict = gen_road_dir_dict(cross_ledger_info) - gen_report_date = datetime.datetime.now().strftime('%Y年%m月%d日') + gen_report_date = datetime.now().strftime('%Y年%m月%d日') file_name = gen_report_file_name(cross_static_info['name'] + '路口优化对比报告' + str(cut_images), date_list + compare_date_list, time_range, parts, gen_report_date) # 优化后 data_range = gen_date_range_str(date_list) @@ -102,11 +105,11 @@ def gen_cross_compare_report(params): dir = os.path.dirname(os.path.abspath(__file__)) localfile_path = f'{dir}/../temp/{file_name}.lock' - with open(localfile_path, 'w') as f: - pass if os.path.exists(localfile_path): return json.dumps(make_common_res(12, '正在生成中,请勿重复提交')) - + with open(localfile_path, 'w') as f: + pass + doc1 = DocDocumentContrastCtx('9660') cut_image_params = { 'crossid': crossid, 'nodeid': nodeid, @@ -143,43 +146,125 @@ def gen_cross_compare_report(params): compared_inroad_delay_infos = parse_comp_inroad_delay_infos(road_flow_delay_infos, comp_road_flow_delay_infos) # 装配数据 title = f"{cross_static_info['name']}路口优化对比报告" + doc1.title = title part1_data = gen_compare_report_part1_data(data_range, compare_date_range, time_range, cross_static_info['name'], final_overview) if 'part1' in parts: + doc1.tpl_paragraph['part1']['visible'] = 1 + doc1.tpl_data['part1_1'].item1 = part1_data['data_range'] + doc1.tpl_data['part1_1'].item2 = part1_data['compare_date_range'] + doc1.tpl_data['part1_1'].item3 = part1_data['cross_name'] + doc1.tpl_data['part1_1'].item4 = part1_data['time_range'] + for item in part1_data['data_list']: + item_detail = PartDetail() + item_detail.detail = item + doc1.tpl_data['part1_1'].table.append(item_detail) if cut_images == 1: part1_data['cut_images'] = True part1_data['cut_image_params'] = cut_image_params part1_data['cut_image_params']['image_part'] = 'part1' # todo 补充自动截图逻辑 if 'part2' in parts: + doc1.tpl_paragraph['part2']['visible'] = 1 if 'part2_1' in parts: + doc1.tpl_paragraph['part2']['part2_1'] = 1 part2_1_data = gen_compare_report_part2_1_data(cross_static_info, cross_ledger_info) + doc1.tpl_data['part2_1'].item1 = part2_1_data['cross_name'] + doc1.tpl_data['part2_1'].item2 = part2_1_data['division'] + doc1.tpl_data['part2_1'].item3 = part2_1_data['cross_model'] + '的' + part2_1_data['cross_type'] + doc1.tpl_data['part2_1'].item4 = part2_1_data['slc_company'] if cut_images == 1: part2_1_data['cut_images'] = True part2_1_data['cut_image_params'] = cut_image_params part2_1_data['cut_image_params']['image_part'] = 'part2_1' # todo 补充自动截图逻辑 if 'part2_2' in parts: + doc1.tpl_paragraph['part2']['part2_2'] = 1 part2_2_data = gen_compare_report_part2_2_data(road_flow_delay_infos, roads_dir_dict) + detail1 = PartDetail() + detail1.detail = part2_2_data['detail'] + doc1.tpl_data['part2_2'].table = [detail1] if cut_images == 1: part2_2_data['cut_images'] = True part2_2_data['cut_image_params'] = cut_image_params part2_2_data['cut_image_params']['image_part'] = 'part2_2' # todo 补充自动截图逻辑 if 'part2_3' in parts: + doc1.tpl_paragraph['part2']['part2_3'] = 1 part2_3_data = gen_compare_report_part2_3_data(road_flow_turn_rate, avg_cross_delay_info, inroad_static_info_dict) + detail1 = PartDetail() + detail1.detail = "根据车辆分流转向比分析,?进口道流量占比最大为?,?进口道流量占比最小为?。路口的主要车流方向为?,?。" + detail1.detail_value = [part2_3_data['max_src_dir'], part2_3_data['max_flow_rate'], part2_3_data['min_src_dir'], part2_3_data['min_flow_rate'], part2_3_data['main_flow_str'], part2_3_data['main_flow_detail']] + doc1.tpl_data['part2_3'].table = [detail1] if cut_images == 1: part2_3_data['cut_images'] = True part2_3_data['cut_image_params'] = cut_image_params part2_3_data['cut_image_params']['image_part'] = 'part2_3' # todo 补充自动截图逻辑 if 'part3' in parts: + doc1.tpl_paragraph['part3']['visible'] = 1 part3_data = gen_compare_report_part3_data(crossid, nodeid, area_id, time_range, tp_start, date_list, avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_phase, is_peak, cross_ledger_info, weekdays) + for problem_key in part3_data.keys(): + class_part = PartDetail() + class_part.item1 = part3_data[problem_key]['class_name'] + for item in part3_data[problem_key]['detail']: + item_part = PartDetail() + item_part.item1 = item['item_name'] + child_item_part = PartDetail() + child_item_part.detail = item['item_detail'] + item_part.table = [child_item_part] + class_part.table.append(item_part) + doc1.tpl_data['part3_1'].table.append(class_part) if 'part4' in parts: - pass + doc1.tpl_paragraph['part4']['visible'] = 1 + if 'part4_1' in parts: + doc1.tpl_paragraph['part4']['part4_1'] = 1 + if 'part4_2' in parts: + doc1.tpl_paragraph['part4']['part4_2'] = 1 if 'part5' in parts: + doc1.tpl_paragraph['part5']['visible'] = 1 part5_data = gen_compare_report_part5_data(part1_data, compared_inroad_delay_infos) + detail5_1 = PartDetail() + detail5_1.item1 = '路口方面' + for item in part5_data['cross_data']['data_list']: + item_detail = PartDetail() + item_detail.detail = item + detail5_1.table.append(item_detail) + table_value = [detail5_1] + for src_dir in part5_data['src_dir_data_dict'].keys(): + detail5_2 = PartDetail() + detail5_2.item1 = src_dir + '进口方面' + for item in part5_data['src_dir_data_dict'][src_dir]['data_list']: + item_detail = PartDetail() + item_detail.detail = item + detail5_2.table.append(item_detail) + table_value.append(detail5_2) + doc1.tpl_data['part5_1'].item1 = '方案下发后通过平台对路口优化效果进行对比,优化后路口及进口道效果提升较明显的指标如下:' + doc1.tpl_data['part5_1'].table = table_value # 清除临时本地文件 os.remove(localfile_path) + file_stream = io.BytesIO() + doc1.build_template('') + doc1.doc.save(file_stream) + file_stream.seek(0) + cos_path = f'user/cross_doctor/task_file' + folder_manager.ensure_folder(cos_path) + cos_key = f"{cos_path}/{cross_static_info['name']}路口优化对比报告.docx" + cos_client.put_object(Bucket=g_cos_bucket, Key=cos_key, Body=file_stream) + download_url = f'{g_cos_root}/{cos_key}' + res = make_common_res(0, 'ok') + res['data'] = { + 'crossid': crossid, + 'nodeid': nodeid, + 'area_id': area_id, + 'name': cross_static_info['name'], + 'file_name': file_name, + 'gen_report_date': gen_report_date, + 'date_range': data_range, + 'compare_date_range': compare_date_range, + 'weekday_str': gen_weekday_str(weekdays), + 'download_url': download_url + } + return json.dumps(res, ensure_ascii=False) def gen_compare_report_part1_data(data_range, compare_date_range, time_range, cross_name, final_overview): @@ -199,31 +284,34 @@ def gen_compare_report_part1_data(data_range, compare_date_range, time_range, cr 'delay_time': '路口延误时间' } for key in ('service_level', 'jam_index', 'stop_times', 'high_park_percent', 'speed', 'delay_time'): - compare_key = 'comp' + key + compare_key = 'comp_' + key if key == 'service_level': service_level_compare_res = compare_service_level(final_overview[key], final_overview[compare_key]) if service_level_compare_res and service_level_compare_res > 0: service_level_compare_str = f"{index_dict[key]}由{final_overview[compare_key]}提升为{final_overview[key]}, 提升{service_level_compare_res}个等级;" part1_data['data_list'].append(service_level_compare_str) elif key in ('jam_index', 'stop_times', 'high_park_percent', 'delay_time'): + if key == 'high_park_percent': + final_overview[key] = int(final_overview[key].replace('%', '')) + final_overview[compare_key] = int(final_overview[compare_key].replace('%', '')) if final_overview[compare_key] and final_overview[key] and final_overview[compare_key] > final_overview[key]: - rate = round(final_overview[key] / final_overview[compare_key] * 100, 2) if final_overview[compare_key] > 0 else 0 - compare_res_str = f"{index_dict[key]}由{final_overview[compare_key]}下降为{final_overview[key]}, 减少{final_overview[key] - final_overview[compare_key]},优化率为{rate}%;" + rate = round((final_overview[key] - final_overview[compare_key]) / final_overview[compare_key] * 100, 2) if final_overview[compare_key] != '-' and final_overview[compare_key] > 0 else 0 + compare_res_str = f"{index_dict[key]}由{final_overview[compare_key]}下降为{final_overview[key]}, 减少{round(final_overview[key] - final_overview[compare_key], 2)},优化率为{rate}%;" part1_data['data_list'].append(compare_res_str) else: if final_overview[compare_key] and final_overview[key] and final_overview[compare_key] < final_overview[key]: - rate = round(final_overview[key] / final_overview[compare_key] * 100, 2) if final_overview[compare_key] > 0 else 0 - compare_res_str = f"{index_dict[key]}由{final_overview[compare_key]}Km/h提升为{final_overview[key]}km/h, 提升{final_overview[key] - final_overview[compare_key]}km/h,提升率为{rate}%;" + rate = round((final_overview[compare_key] - final_overview[key]) / final_overview[compare_key] * 100, 2) if final_overview[compare_key] != '-' and final_overview[compare_key] > 0 else 0 + compare_res_str = f"{index_dict[key]}由{final_overview[compare_key]}Km/h提升为{final_overview[key]}km/h, 提升{round(final_overview[key] - final_overview[compare_key], 2)}km/h,提升率为{rate}%;" part1_data['data_list'].append(compare_res_str) return part1_data def gen_compare_report_part2_1_data(cross_static_info, cross_ledger_info): cross_type_dict = db_tmnet.gen_cross_type_dict() - cross_type = cross_type_dict[int(cross_ledger_info['data']['ledger']['cross_type'])] if cross_ledger_info['data']['ledger']['cross_type'] and int(cross_ledger_info['data']['ledger']['cross_type']) in cross_type_dict.keys() else '' + cross_type = cross_type_dict[int(cross_ledger_info['ledger']['cross_type'])] if cross_ledger_info['ledger']['cross_type'] and int(cross_ledger_info['ledger']['cross_type']) in cross_type_dict.keys() else '' part2_1_data = { 'cross_name': cross_static_info['name'], - 'division': cross_ledger_info['data']['ledger']['division'], + 'division': cross_ledger_info['ledger']['division'], 'cross_model': cross_static_info['cross_model'], 'cross_type': cross_type, 'slc_company': cross_static_info['slc_company'] @@ -240,7 +328,7 @@ def gen_compare_report_part2_2_data(road_flow_delay_infos, roads_dir_dict): err_dir_list = [] for roadid in road_flow_delay_infos.keys(): if road_flow_delay_infos[roadid]['service_level'] in ('E', 'F'): - item_str = f"{road_dir[roadid]}进口的延误时间为{road_flow_delay_infos[roadid]['delay_time']}s" + item_str = f"{srcDir_toStr(road_dir[roadid])}进口的延误时间为{road_flow_delay_infos[roadid]['delay_time']}s" part2_2_data['total_num'] += 1 err_dir_list.append(item_str) total_str = '' @@ -302,7 +390,7 @@ def gen_compare_report_part2_3_data(road_flow_turn_rate, avg_cross_delay_info, i part2_3_data = { 'max_src_dir': flow_rate_dict['max']['src_dir'], 'max_flow_rate': str(flow_rate_dict['max']['flow_rate']) + '%', - 'mi_src_dirn': flow_rate_dict['min']['src_dir'], + 'min_src_dir': flow_rate_dict['min']['src_dir'], 'min_flow_rate': str(flow_rate_dict['min']['flow_rate']) + '%', 'main_flow_str': main_flow_str, 'main_flow_detail': ';'.join(main_flow_detail) @@ -322,19 +410,20 @@ def gen_compare_report_part3_data(crossid, nodeid, area_id, time_range, tp_start for problem_key in cross_problems.keys(): if problem_key != 'phase_problems': if 'total_num' in cross_problems[problem_key].keys() and cross_problems[problem_key]['total_num'] > 0: - if problem_key not in problem_key_dict.keys(): + if problem_key not in problem_detail_dict.keys(): problem_detail_dict[problem_key] = { 'class_name': problem_key_dict[problem_key], 'detail': [] } - problem_infos = cross_problems[problem_key]['values']['problem_infos'] - problem_detail_dict[problem_key]['detail'].append({ - 'item_name': problem_infos['item_name'], - 'item_detail': problem_infos['item_detail_str'] - }) + problem_infos = cross_problems[problem_key]['values'] + for problem_item in problem_infos: + problem_detail_dict[problem_key]['detail'].append({ + 'item_name': problem_item['problem_infos']['item_name'], + 'item_detail': problem_item['problem_infos']['item_detail_str'] + }) else: if 'total_num' in cross_problems[problem_key].keys() and cross_problems[problem_key]['total_num'] > 0: - if problem_key not in problem_key_dict.keys(): + if problem_key not in problem_detail_dict.keys(): problem_detail_dict[problem_key] = { 'class_name': problem_key_dict[problem_key], 'detail': [] @@ -384,23 +473,27 @@ def gen_compare_report_part5_data(part1_data, compared_inroad_delay_infos): for roadid in compared_inroad_delay_infos.keys(): src_dir = compared_inroad_delay_infos[roadid]['src_dir'] src_dir_data = [] - compare_data = compared_inroad_delay_infos[roadid]['comp_data'] - item_data = compared_inroad_delay_infos[roadid]['item_data'] - for key in ('service_level', 'jam_index', 'stop_times', 'high_park_percent', 'speed', 'delay_time'): + compare_data = compared_inroad_delay_infos[roadid]['dir_data']['comp_data'] + item_data = compared_inroad_delay_infos[roadid]['dir_data']['item_data'] + diff_data = compared_inroad_delay_infos[roadid]['dir_data']['diff_data'] + for key in ('service_level', 'stop_times', 'high_park_percent', 'speed', 'delay_time'): if key == 'service_level': service_level_compare_res = compare_service_level(item_data[key], compare_data[key]) if service_level_compare_res and service_level_compare_res > 0: service_level_compare_str = f"{index_dict[key]}由{compare_data[key]}提升为{item_data[key]}, 提升{service_level_compare_res}个等级;" src_dir_data.append(service_level_compare_str) - elif key in ('jam_index', 'stop_times', 'high_park_percent', 'delay_time'): + elif key in ('stop_times', 'high_park_percent', 'delay_time'): if compare_data[key] and item_data[key] and compare_data[key] > item_data[key]: - rate = round(item_data[key] / compare_data[key] * 100, 2) if compare_data[key] > 0 else 0 - compare_res_str = f"{index_dict[key]}由{compare_data[key]}下降为{item_data[key]}, 减少{item_data[key] - compare_data[key]},优化率为{rate}%;" + if key == 'high_park_percent': + item_data[key] = int(item_data[key].replace('%', '')) + compare_data[key] = int(compare_data[key].replace('%', '')) + rate = round((item_data[key] - compare_data[key]) / compare_data[key] * 100, 2) if compare_data[key] != '-' and compare_data[key] > 0 else 0 + compare_res_str = f"{index_dict[key]}由{compare_data[key]}下降为{item_data[key]}, 减少{diff_data[key]},优化率为{rate}%;" src_dir_data.append(compare_res_str) else: if compare_data[key] and item_data[key] and compare_data[key] < item_data[key]: - rate = round(item_data[key] / compare_data[key] * 100, 2) if compare_data[key] > 0 else 0 - compare_res_str = f"{index_dict[key]}由{compare_data[key]}Km/h提升为{item_data[key]}km/h, 提升{item_data[key] - compare_data[key]}km/h,提升率为{rate}%;" + rate = round((compare_data[key] - item_data[key]) / compare_data[key] * 100, 2) if compare_data[key] != '-' and compare_data[key] > 0 else 0 + compare_res_str = f"{index_dict[key]}由{compare_data[key]}Km/h提升为{item_data[key]}km/h, 提升{diff_data[key]}km/h,提升率为{rate}%;" src_dir_data.append(compare_res_str) if len(src_dir_data) > 0: part5_data['src_dir_data_dict'][srcDir_toStr(src_dir)] = { diff --git a/app/task_worker.py b/app/task_worker.py index 4210dd1..145a074 100644 --- a/app/task_worker.py +++ b/app/task_worker.py @@ -3202,4 +3202,14 @@ def export_cross_monitor_week_report(params): return res -# 以下内容为路口优化任务相关 +# 以下内容为路口优化任务相关 20260518 +def query_cross_optimize_additional_info(task_no, nodeid, area_id): + """ + 获取路口优化任务补充信息 + :param task_no: 任务编码 + :param nodeid: 城市id + :param area_id: 辖区id + :return: 路口优化任务补充信息 + """ + + pass diff --git a/tool/compare_report.py b/tool/compare_report.py index fb82ba0..b283522 100644 --- a/tool/compare_report.py +++ b/tool/compare_report.py @@ -407,8 +407,8 @@ class DocDocumentContrastCtx: # set_font(para, para.text, '仿宋_GB2312', 30,font_color=(255, 0, 0), bg_color='FFFF00') # for para in self.doc.paragraphs: # set_font(para, para.text, '仿宋', 14) - self.doc.save(self.get_static_file_path() + f"/{file_name}.docx") - return f"/api/phase_template_download?nodeid={self.nodeid}&type=report&file_name={file_name}" + # self.doc.save(self.get_static_file_path() + f"/{file_name}.docx") + # return f"/api/phase_template_download?nodeid={self.nodeid}&type=report&file_name={file_name}" def set_font(para, text_to_find, font_name='仿宋', font_size=12, font_color=(0, 0, 0), bg_color='FFFFFF'): diff --git a/tool/cross_monitor_week_report.py b/tool/cross_monitor_week_report.py index 77872f6..ef45ba8 100644 --- a/tool/cross_monitor_week_report.py +++ b/tool/cross_monitor_week_report.py @@ -276,7 +276,7 @@ def fill_report_template(data): file_stream = io.BytesIO() doc.save(file_stream) file_stream.seek(0) - doc.save('./text.docx') + # doc.save('./text.docx') cos_path = f'user/cross_doctor/task_file' folder_manager.ensure_folder(cos_path) cos_key = f"{cos_path}/{city_name}第{week_num}周路口巡检周报.docx"