增加公交线路和编码功能
This commit is contained in:
2
app.py
2
app.py
@@ -160,4 +160,4 @@ if __name__ == '__main__':
|
|||||||
port = int(os.environ.get('DEPLOY_RUN_PORT', os.environ.get('PORT', 5000)))
|
port = int(os.environ.get('DEPLOY_RUN_PORT', os.environ.get('PORT', 5000)))
|
||||||
log_info(f'启动服务器:http://localhost:{port}', 'app')
|
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')
|
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)
|
||||||
@@ -173,6 +173,10 @@ FIELD_MAPPING = {
|
|||||||
# 自定义计算字段(虚拟字段)
|
# 自定义计算字段(虚拟字段)
|
||||||
'custom_service_fee': '自定义服务费(元)',
|
'custom_service_fee': '自定义服务费(元)',
|
||||||
'total_amount': '实收金额(元)',
|
'total_amount': '实收金额(元)',
|
||||||
|
|
||||||
|
# 车辆信息(从 t_car 表关联)
|
||||||
|
'car_bus_path': '公交线路',
|
||||||
|
'car_sn': '车辆编码',
|
||||||
}
|
}
|
||||||
|
|
||||||
# 获取字段中文名称
|
# 获取字段中文名称
|
||||||
|
|||||||
@@ -340,9 +340,9 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
|||||||
report_date = start_time.strftime('%Y-%m-%d')
|
report_date = start_time.strftime('%Y-%m-%d')
|
||||||
delete_old_history(config_id, report_date, config['split_type'], config['split_value'])
|
delete_old_history(config_id, report_date, config['split_type'], config['split_value'])
|
||||||
|
|
||||||
# 构建查询SQL - 过滤掉虚拟字段(时段电量、自定义服务费、实收金额等)
|
# 构建查询SQL - 过滤掉虚拟字段(时段电量、自定义服务费、实收金额、车辆信息等)
|
||||||
# 虚拟字段不是数据库表中的实际字段,需要动态计算
|
# 虚拟字段不是数据库表中的实际字段,需要动态计算或关联查询
|
||||||
VIRTUAL_FIELDS = {'sharp_electricity', 'peak_electricity', 'flat_electricity', 'valley_electricity', 'custom_service_fee', 'total_amount'}
|
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]
|
db_fields = [f for f in selected_fields if f not in VIRTUAL_FIELDS]
|
||||||
|
|
||||||
# 确保 charge_degree 总是被查询(用于计算总电量)
|
# 确保 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:
|
if 'order_no' not in db_fields:
|
||||||
db_fields.append('order_no')
|
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)
|
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:
|
if finish_type is not None:
|
||||||
order['finish_msg'] = get_finish_reason(finish_type, finish_code, finish_msg)
|
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 表示补单结束)
|
# 检查是否有补单记录(finish_type = 2 表示补单结束)
|
||||||
has_supplement = any(order.get('finish_type') == 2 for order in orders)
|
has_supplement = any(order.get('finish_type') == 2 for order in orders)
|
||||||
if has_supplement:
|
if has_supplement:
|
||||||
|
|||||||
@@ -172,15 +172,33 @@ function onFieldCheckboxChange(cb) {
|
|||||||
const item = cb.closest('.checkbox-item');
|
const item = cb.closest('.checkbox-item');
|
||||||
if (item) item.classList.toggle('checked', cb.checked);
|
if (item) item.classList.toggle('checked', cb.checked);
|
||||||
|
|
||||||
|
// 获取当前已选字段的顺序(从字段顺序列表中获取)
|
||||||
|
const currentOrder = getSelectedFieldsOrder();
|
||||||
|
|
||||||
|
// 获取所有勾选的字段
|
||||||
const fieldsList = document.getElementById('field-list');
|
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 sumFieldsList = document.getElementById('sum-fields-list');
|
||||||
const currentSumFields = sumFieldsList ? Array.from(sumFieldsList.querySelectorAll('input:checked')).map(c => c.value) : [];
|
const currentSumFields = sumFieldsList ? Array.from(sumFieldsList.querySelectorAll('input:checked')).map(c => c.value) : [];
|
||||||
|
|
||||||
refreshSumFieldsList(checkedFields, currentSumFields);
|
refreshSumFieldsList(newOrder, currentSumFields);
|
||||||
refreshSelectedFieldsOrder(checkedFields);
|
refreshSelectedFieldsOrder(newOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新已选字段顺序列表
|
// 刷新已选字段顺序列表
|
||||||
|
|||||||
Reference in New Issue
Block a user