diff --git a/app.py b/app.py index 427d63d..5ff80d4 100644 --- a/app.py +++ b/app.py @@ -160,4 +160,4 @@ if __name__ == '__main__': port = int(os.environ.get('DEPLOY_RUN_PORT', os.environ.get('PORT', 5000))) log_info(f'启动服务器:http://localhost:{port}', 'app') log_info(f'数据库:{os.environ.get("DB_HOST", "haoslm2.xicp.net")}:{os.environ.get("DB_PORT", "10216")}', 'app') - app.run(host='0.0.0.0', port=port, debug=True) + app.run(host='0.0.0.0', port=port, debug=True) \ No newline at end of file diff --git a/lib/field_mapping.py b/lib/field_mapping.py index ad5693b..a87ee6e 100644 --- a/lib/field_mapping.py +++ b/lib/field_mapping.py @@ -173,6 +173,10 @@ FIELD_MAPPING = { # 自定义计算字段(虚拟字段) 'custom_service_fee': '自定义服务费(元)', 'total_amount': '实收金额(元)', + + # 车辆信息(从 t_car 表关联) + 'car_bus_path': '公交线路', + 'car_sn': '车辆编码', } # 获取字段中文名称 diff --git a/lib/report_generator.py b/lib/report_generator.py index a632b45..0b41630 100644 --- a/lib/report_generator.py +++ b/lib/report_generator.py @@ -340,9 +340,9 @@ def generate_daily_report(config_id, start_time=None, end_time=None): report_date = start_time.strftime('%Y-%m-%d') delete_old_history(config_id, report_date, config['split_type'], config['split_value']) - # 构建查询SQL - 过滤掉虚拟字段(时段电量、自定义服务费、实收金额等) - # 虚拟字段不是数据库表中的实际字段,需要动态计算 - VIRTUAL_FIELDS = {'sharp_electricity', 'peak_electricity', 'flat_electricity', 'valley_electricity', 'custom_service_fee', 'total_amount'} + # 构建查询SQL - 过滤掉虚拟字段(时段电量、自定义服务费、实收金额、车辆信息等) + # 虚拟字段不是数据库表中的实际字段,需要动态计算或关联查询 + VIRTUAL_FIELDS = {'sharp_electricity', 'peak_electricity', 'flat_electricity', 'valley_electricity', 'custom_service_fee', 'total_amount', 'car_bus_path', 'car_sn'} db_fields = [f for f in selected_fields if f not in VIRTUAL_FIELDS] # 确保 charge_degree 总是被查询(用于计算总电量) @@ -357,6 +357,11 @@ def generate_daily_report(config_id, start_time=None, end_time=None): if 'order_no' not in db_fields: db_fields.append('order_no') + # 如果选择了车辆信息字段,需要确保查询 charge_vin(用于关联 t_car 表) + need_car_info = 'car_bus_path' in selected_fields or 'car_sn' in selected_fields + if need_car_info and 'charge_vin' not in db_fields: + db_fields.append('charge_vin') + fields_str = ', '.join(db_fields) # 检查是否为多选值(逗号分隔) @@ -405,6 +410,32 @@ def generate_daily_report(config_id, start_time=None, end_time=None): if finish_type is not None: order['finish_msg'] = get_finish_reason(finish_type, finish_code, finish_msg) + # 如果需要车辆信息,从 t_car 表关联查询 + if need_car_info and orders: + # 获取所有 VIN 码 + vin_list = list(set(order.get('charge_vin') for order in orders if order.get('charge_vin'))) + if vin_list: + placeholders = ', '.join(['%s'] * len(vin_list)) + car_sql = f""" + SELECT car_vin, car_bus_path, car_sn + FROM t_car + WHERE car_vin IN ({placeholders}) + """ + car_results = execute_query(car_sql, tuple(vin_list)) + car_map = {car['car_vin']: car for car in car_results} + + # 将车辆信息添加到订单中 + for order in orders: + vin = order.get('charge_vin') + if vin and vin in car_map: + car_info = car_map[vin] + order['car_bus_path'] = car_info.get('car_bus_path', '') + order['car_sn'] = car_info.get('car_sn', '') + else: + order['car_bus_path'] = '' + order['car_sn'] = '' + log_info(f"[日报生成] 关联查询到 {len(car_map)} 条车辆信息", 'report') + # 检查是否有补单记录(finish_type = 2 表示补单结束) has_supplement = any(order.get('finish_type') == 2 for order in orders) if has_supplement: diff --git a/public/static/js/config.js b/public/static/js/config.js index 15ad49d..8a6b713 100644 --- a/public/static/js/config.js +++ b/public/static/js/config.js @@ -172,15 +172,33 @@ function onFieldCheckboxChange(cb) { const item = cb.closest('.checkbox-item'); if (item) item.classList.toggle('checked', cb.checked); + // 获取当前已选字段的顺序(从字段顺序列表中获取) + const currentOrder = getSelectedFieldsOrder(); + + // 获取所有勾选的字段 const fieldsList = document.getElementById('field-list'); - const checkedFields = Array.from(fieldsList.querySelectorAll('input:checked')).map(c => c.value); + const allCheckedFields = Array.from(fieldsList.querySelectorAll('input:checked')).map(c => c.value); + + // 构建新的字段顺序:保留当前顺序,添加新勾选的字段,移除取消勾选的字段 + let newOrder = []; + for (const fieldKey of currentOrder) { + if (allCheckedFields.includes(fieldKey)) { + newOrder.push(fieldKey); + } + } + // 添加新勾选的字段(不在当前顺序中的) + for (const fieldKey of allCheckedFields) { + if (!newOrder.includes(fieldKey)) { + newOrder.push(fieldKey); + } + } // 保留当前求和字段的选择状态 const sumFieldsList = document.getElementById('sum-fields-list'); const currentSumFields = sumFieldsList ? Array.from(sumFieldsList.querySelectorAll('input:checked')).map(c => c.value) : []; - refreshSumFieldsList(checkedFields, currentSumFields); - refreshSelectedFieldsOrder(checkedFields); + refreshSumFieldsList(newOrder, currentSumFields); + refreshSelectedFieldsOrder(newOrder); } // 刷新已选字段顺序列表