feat: 添加字段自定义报表名头功能
Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 9894087
This commit is contained in:
15
app.py
15
app.py
@@ -67,6 +67,7 @@ def create_config():
|
||||
time_periods = data.get('time_periods', {})
|
||||
merge_telecom = 1 if data.get('merge_telecom') else 0
|
||||
telecom_vehicle_no = data.get('telecom_vehicle_no', '')
|
||||
field_custom_names = data.get('field_custom_names', {})
|
||||
|
||||
if not config_name or not split_type or not split_value:
|
||||
return jsonify({'success': False, 'message': '缺少必填字段'}), 400
|
||||
@@ -84,8 +85,8 @@ def create_config():
|
||||
sql = """
|
||||
INSERT INTO t_daily_report_config
|
||||
(id, config_name, split_type, split_value, split_name, selected_fields,
|
||||
sum_fields, time_periods, merge_telecom, telecom_vehicle_no, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 1, %s, NOW(), NOW())
|
||||
sum_fields, time_periods, merge_telecom, telecom_vehicle_no, field_custom_names, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 1, %s, NOW(), NOW())
|
||||
"""
|
||||
|
||||
params = (
|
||||
@@ -99,6 +100,7 @@ def create_config():
|
||||
json.dumps(time_periods, ensure_ascii=False),
|
||||
merge_telecom,
|
||||
telecom_vehicle_no,
|
||||
json.dumps(field_custom_names, ensure_ascii=False) if field_custom_names else None,
|
||||
sort_order
|
||||
)
|
||||
|
||||
@@ -127,12 +129,13 @@ def update_config(config_id):
|
||||
time_periods = data.get('time_periods', {})
|
||||
merge_telecom = 1 if data.get('merge_telecom') else 0
|
||||
telecom_vehicle_no = data.get('telecom_vehicle_no', '')
|
||||
field_custom_names = data.get('field_custom_names', {})
|
||||
|
||||
sql = """
|
||||
UPDATE t_daily_report_config
|
||||
SET config_name = %s, split_type = %s, split_value = %s, split_name = %s,
|
||||
selected_fields = %s, sum_fields = %s, time_periods = %s,
|
||||
merge_telecom = %s, telecom_vehicle_no = %s, update_time = NOW()
|
||||
merge_telecom = %s, telecom_vehicle_no = %s, field_custom_names = %s, update_time = NOW()
|
||||
WHERE id = %s
|
||||
"""
|
||||
|
||||
@@ -146,6 +149,7 @@ def update_config(config_id):
|
||||
json.dumps(time_periods, ensure_ascii=False),
|
||||
merge_telecom,
|
||||
telecom_vehicle_no,
|
||||
json.dumps(field_custom_names, ensure_ascii=False) if field_custom_names else None,
|
||||
config_id
|
||||
)
|
||||
|
||||
@@ -188,8 +192,8 @@ def copy_config(config_id):
|
||||
# 插入新配置
|
||||
execute_insert(
|
||||
'''INSERT INTO t_daily_report_config
|
||||
(id, config_name, split_type, split_value, split_name, selected_fields, sum_fields, time_periods, merge_telecom, telecom_vehicle_no, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())''',
|
||||
(id, config_name, split_type, split_value, split_name, selected_fields, sum_fields, time_periods, merge_telecom, telecom_vehicle_no, field_custom_names, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())''',
|
||||
(
|
||||
new_id,
|
||||
new_name,
|
||||
@@ -201,6 +205,7 @@ def copy_config(config_id):
|
||||
original.get('time_periods', ''),
|
||||
original.get('merge_telecom', 0),
|
||||
original.get('telecom_vehicle_no', ''),
|
||||
original.get('field_custom_names', None),
|
||||
original['is_active'],
|
||||
sort_order
|
||||
)
|
||||
|
||||
@@ -416,7 +416,8 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
||||
split_name=config.get('split_name', config['split_value']),
|
||||
start_time=start_time_str,
|
||||
end_time=end_time_str,
|
||||
id_name_maps=id_name_maps
|
||||
id_name_maps=id_name_maps,
|
||||
field_custom_names=config.get('field_custom_names')
|
||||
)
|
||||
|
||||
print(f"[日报生成] Excel文件已生成: {file_path}")
|
||||
@@ -491,12 +492,13 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
||||
|
||||
def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
config_name, split_name, start_time, end_time,
|
||||
id_name_maps=None):
|
||||
id_name_maps=None, field_custom_names=None):
|
||||
"""
|
||||
生成Excel文件
|
||||
|
||||
Args:
|
||||
id_name_maps: ID到名称的映射字典,格式为 {field_name: {id_value: name_value}}
|
||||
field_custom_names: 字段自定义名头字典,格式为 {field_key: custom_name}
|
||||
|
||||
Returns:
|
||||
str: 文件路径
|
||||
@@ -532,10 +534,14 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
|
||||
# 写入表头(中文)
|
||||
header_row = 4
|
||||
field_custom_names = field_custom_names or {}
|
||||
for col_idx, field in enumerate(selected_fields, 1):
|
||||
cell = ws.cell(row=header_row, column=col_idx)
|
||||
# 优先使用自定义名头
|
||||
if field in field_custom_names and field_custom_names[field]:
|
||||
display_name = field_custom_names[field]
|
||||
# 如果是ID字段且有名称映射,表头显示为名称而不是ID
|
||||
if field in id_name_maps and id_name_maps[field]:
|
||||
elif field in id_name_maps and id_name_maps[field]:
|
||||
# 将"用户ID"改为"用户","企业ID"改为"企业"等
|
||||
display_name = get_field_display_name(field).replace('ID', '')
|
||||
else:
|
||||
|
||||
@@ -1125,6 +1125,9 @@
|
||||
document.getElementById('split-type').value = '';
|
||||
document.getElementById('split-value').innerHTML = '<option value="">请先选择拆分方式</option>';
|
||||
|
||||
// 重置字段自定义名头
|
||||
fieldCustomNames = {};
|
||||
|
||||
// 重置合并特来电配置
|
||||
const mergeTelecomCheckbox = document.getElementById('merge-telecom');
|
||||
const telecomVehicleNoInput = document.getElementById('telecom-vehicle-no');
|
||||
@@ -1212,12 +1215,20 @@
|
||||
refreshSelectedFieldsOrder(checkedFields);
|
||||
}
|
||||
|
||||
// 字段自定义名头存储
|
||||
let fieldCustomNames = {};
|
||||
|
||||
// 刷新已选字段顺序列表
|
||||
function refreshSelectedFieldsOrder(selectedFields) {
|
||||
function refreshSelectedFieldsOrder(selectedFields, customNames = null) {
|
||||
const orderGroup = document.getElementById('selected-fields-order-group');
|
||||
const orderList = document.getElementById('selected-fields-order');
|
||||
if (!orderList) return;
|
||||
|
||||
// 如果传入了自定义名头,更新全局变量
|
||||
if (customNames !== null) {
|
||||
fieldCustomNames = {...customNames};
|
||||
}
|
||||
|
||||
// 根据是否有已选字段,显示/隐藏字段顺序区域
|
||||
if (orderGroup) {
|
||||
orderGroup.style.display = selectedFields.length > 0 ? 'block' : 'none';
|
||||
@@ -1229,12 +1240,16 @@
|
||||
orderList.innerHTML = selectedFields.map((fieldKey, index) => {
|
||||
const field = allFields.find(f => f.key === fieldKey);
|
||||
const displayName = field ? field.display : fieldKey;
|
||||
const customName = fieldCustomNames[fieldKey] || '';
|
||||
const isFirst = index === 0;
|
||||
const isLast = index === selectedFields.length - 1;
|
||||
return `
|
||||
<div class="selected-field-item" data-field="${fieldKey}">
|
||||
<span class="field-index">#${index + 1}</span>
|
||||
<span class="field-name">${displayName}</span>
|
||||
<span class="field-name" title="${displayName}">${displayName}</span>
|
||||
<input type="text" class="field-custom-name" placeholder="自定义报表名头" value="${customName}"
|
||||
onchange="updateFieldCustomName('${fieldKey}', this.value)"
|
||||
style="flex: 1; min-width: 100px; padding: 4px 8px; font-size: 12px;">
|
||||
<div class="field-actions">
|
||||
<button type="button" class="btn-move" onclick="moveFieldUp(${index})" ${isFirst ? 'disabled' : ''} title="上移">↑</button>
|
||||
<button type="button" class="btn-move" onclick="moveFieldDown(${index})" ${isLast ? 'disabled' : ''} title="下移">↓</button>
|
||||
@@ -1244,6 +1259,20 @@
|
||||
}).join('');
|
||||
}
|
||||
}
|
||||
|
||||
// 更新字段自定义名头
|
||||
function updateFieldCustomName(fieldKey, customName) {
|
||||
if (customName && customName.trim()) {
|
||||
fieldCustomNames[fieldKey] = customName.trim();
|
||||
} else {
|
||||
delete fieldCustomNames[fieldKey];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取字段自定义名头
|
||||
function getFieldCustomNames() {
|
||||
return {...fieldCustomNames};
|
||||
}
|
||||
|
||||
// 字段上移
|
||||
function moveFieldUp(index) {
|
||||
@@ -1631,6 +1660,9 @@
|
||||
alert('请输入特来电车量自编号');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取字段自定义名头
|
||||
const fieldCustomNamesData = getFieldCustomNames();
|
||||
|
||||
const data = {
|
||||
config_name: configName,
|
||||
@@ -1641,7 +1673,8 @@
|
||||
sum_fields: sumFields,
|
||||
time_periods: timePeriods,
|
||||
merge_telecom: mergeTelecom,
|
||||
telecom_vehicle_no: telecomVehicleNo
|
||||
telecom_vehicle_no: telecomVehicleNo,
|
||||
field_custom_names: fieldCustomNamesData
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -1697,8 +1730,9 @@
|
||||
// 加载字段并回显选中状态
|
||||
await loadFields(config.selected_fields, config.sum_fields);
|
||||
|
||||
// 加载字段顺序
|
||||
refreshSelectedFieldsOrder(config.selected_fields);
|
||||
// 加载字段顺序和自定义名头
|
||||
const customNames = config.field_custom_names || {};
|
||||
refreshSelectedFieldsOrder(config.selected_fields, customNames);
|
||||
|
||||
// 初始化时段编辑器并加载配置
|
||||
initTimePeriodEditor();
|
||||
|
||||
Reference in New Issue
Block a user