feat: 报表中ID字段自动转换为对应的名称显示
Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 9894087
This commit is contained in:
@@ -12,6 +12,61 @@ from lib.db import execute_query, execute_insert
|
|||||||
from lib.field_mapping import get_field_display_name
|
from lib.field_mapping import get_field_display_name
|
||||||
|
|
||||||
|
|
||||||
|
# ID字段到名称的映射配置
|
||||||
|
# key: 订单表中的ID字段名
|
||||||
|
# value: (关联表名, 关联表ID字段, 关联表名称字段)
|
||||||
|
ID_TO_NAME_MAPPING = {
|
||||||
|
'user_id': ('t_user', 'id', 'user_name'),
|
||||||
|
'company_id': ('t_company', 'id', 'company_name'),
|
||||||
|
'station_id': ('t_station', 'id', 'station_name'),
|
||||||
|
'equipment_id': ('t_equipment', 'id', 'equipment_name'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def build_id_to_name_map(orders, selected_fields):
|
||||||
|
"""
|
||||||
|
构建ID到名称的映射字典
|
||||||
|
|
||||||
|
Args:
|
||||||
|
orders: 订单数据列表
|
||||||
|
selected_fields: 选中的字段列表
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: {field_name: {id_value: name_value}}
|
||||||
|
"""
|
||||||
|
id_name_maps = {}
|
||||||
|
|
||||||
|
for field in selected_fields:
|
||||||
|
if field not in ID_TO_NAME_MAPPING:
|
||||||
|
continue
|
||||||
|
|
||||||
|
table_name, id_field, name_field = ID_TO_NAME_MAPPING[field]
|
||||||
|
|
||||||
|
# 收集所有需要查询的ID值
|
||||||
|
id_values = set()
|
||||||
|
for order in orders:
|
||||||
|
val = order.get(field)
|
||||||
|
if val is not None and val != '' and val != 0:
|
||||||
|
id_values.add(str(val))
|
||||||
|
|
||||||
|
if not id_values:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 批量查询名称
|
||||||
|
placeholders = ', '.join(['%s'] * len(id_values))
|
||||||
|
sql = f"SELECT {id_field} AS id_val, {name_field} AS name_val FROM {table_name} WHERE {id_field} IN ({placeholders})"
|
||||||
|
|
||||||
|
try:
|
||||||
|
results = execute_query(sql, tuple(id_values))
|
||||||
|
id_name_maps[field] = {str(row['id_val']): row['name_val'] for row in results}
|
||||||
|
print(f"[ID转换] {field}: 查询到 {len(results)} 个名称映射")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ID转换] {field} 查询失败: {e}")
|
||||||
|
id_name_maps[field] = {}
|
||||||
|
|
||||||
|
return id_name_maps
|
||||||
|
|
||||||
|
|
||||||
def get_beijing_time():
|
def get_beijing_time():
|
||||||
"""获取北京时间"""
|
"""获取北京时间"""
|
||||||
beijing_tz = pytz.timezone('Asia/Shanghai')
|
beijing_tz = pytz.timezone('Asia/Shanghai')
|
||||||
@@ -128,6 +183,9 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
|||||||
total = sum(float(order.get(field, 0) or 0) for order in orders)
|
total = sum(float(order.get(field, 0) or 0) for order in orders)
|
||||||
sum_results[field] = total
|
sum_results[field] = total
|
||||||
|
|
||||||
|
# 构建ID到名称的映射
|
||||||
|
id_name_maps = build_id_to_name_map(orders, selected_fields)
|
||||||
|
|
||||||
# 生成Excel文件
|
# 生成Excel文件
|
||||||
file_path = generate_excel(
|
file_path = generate_excel(
|
||||||
orders=orders,
|
orders=orders,
|
||||||
@@ -137,7 +195,8 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
|||||||
config_name=config['config_name'],
|
config_name=config['config_name'],
|
||||||
split_name=config.get('split_name', config['split_value']),
|
split_name=config.get('split_name', config['split_value']),
|
||||||
start_time=start_time_str,
|
start_time=start_time_str,
|
||||||
end_time=end_time_str
|
end_time=end_time_str,
|
||||||
|
id_name_maps=id_name_maps
|
||||||
)
|
)
|
||||||
|
|
||||||
print(f"[日报生成] Excel文件已生成: {file_path}")
|
print(f"[日报生成] Excel文件已生成: {file_path}")
|
||||||
@@ -211,13 +270,19 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
|||||||
|
|
||||||
|
|
||||||
def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||||
config_name, split_name, start_time, end_time):
|
config_name, split_name, start_time, end_time,
|
||||||
|
id_name_maps=None):
|
||||||
"""
|
"""
|
||||||
生成Excel文件
|
生成Excel文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
id_name_maps: ID到名称的映射字典,格式为 {field_name: {id_value: name_value}}
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: 文件路径
|
str: 文件路径
|
||||||
"""
|
"""
|
||||||
|
if id_name_maps is None:
|
||||||
|
id_name_maps = {}
|
||||||
# 创建reports目录
|
# 创建reports目录
|
||||||
reports_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'public', 'reports')
|
reports_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'public', 'reports')
|
||||||
os.makedirs(reports_dir, exist_ok=True)
|
os.makedirs(reports_dir, exist_ok=True)
|
||||||
@@ -249,7 +314,13 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
|||||||
header_row = 4
|
header_row = 4
|
||||||
for col_idx, field in enumerate(selected_fields, 1):
|
for col_idx, field in enumerate(selected_fields, 1):
|
||||||
cell = ws.cell(row=header_row, column=col_idx)
|
cell = ws.cell(row=header_row, column=col_idx)
|
||||||
cell.value = get_field_display_name(field)
|
# 如果是ID字段且有名称映射,表头显示为名称而不是ID
|
||||||
|
if field in id_name_maps and id_name_maps[field]:
|
||||||
|
# 将"用户ID"改为"用户","企业ID"改为"企业"等
|
||||||
|
display_name = get_field_display_name(field).replace('ID', '')
|
||||||
|
else:
|
||||||
|
display_name = get_field_display_name(field)
|
||||||
|
cell.value = display_name
|
||||||
cell.font = Font(bold=True)
|
cell.font = Font(bold=True)
|
||||||
cell.fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')
|
cell.fill = PatternFill(start_color='D3D3D3', end_color='D3D3D3', fill_type='solid')
|
||||||
cell.alignment = Alignment(horizontal='center')
|
cell.alignment = Alignment(horizontal='center')
|
||||||
@@ -265,6 +336,13 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
|||||||
if isinstance(value, datetime):
|
if isinstance(value, datetime):
|
||||||
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
# 将ID转换为名称
|
||||||
|
if field in id_name_maps and value is not None and value != '':
|
||||||
|
name_map = id_name_maps[field]
|
||||||
|
name_value = name_map.get(str(value))
|
||||||
|
if name_value:
|
||||||
|
value = name_value
|
||||||
|
|
||||||
cell.value = value
|
cell.value = value
|
||||||
|
|
||||||
# 写入求和行
|
# 写入求和行
|
||||||
|
|||||||
Reference in New Issue
Block a user