feat: 规范报表名称格式,添加补单检测,设置充电量为必选字段

Coze-Commit-Type: user
Coze-User-ID: 3722323274763196
Coze-Conversation-ID: 9894087
This commit is contained in:
user9994793890
2026-07-13 13:39:58 +08:00
parent f7d0792fff
commit c104b56add
2 changed files with 68 additions and 13 deletions

View File

@@ -376,6 +376,11 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
for order in orders:
order['data_source'] = '驿来特'
# 检查是否有补单记录(finish_type = 2 表示补单结束)
has_supplement = any(order.get('finish_type') == 2 for order in orders)
if has_supplement:
print(f"[日报生成] 检测到补单记录,将在文件名中添加标记")
# 检查是否需要合并特来电数据
merge_telecom = config.get('merge_telecom', 0)
telecom_vehicle_no = config.get('telecom_vehicle_no', '')
@@ -390,6 +395,9 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
# 将特来电数据添加到订单列表
orders.extend(telecom_orders)
print(f"[日报生成] 合并后总订单数: {len(orders)}")
# 检查特来电数据中是否有补单记录
if not has_supplement:
has_supplement = any(order.get('finish_type') == 2 for order in telecom_orders)
if not orders:
# 即使没有数据,也保存一条失败记录
@@ -455,7 +463,8 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
start_time=start_time_str,
end_time=end_time_str,
id_name_maps=id_name_maps,
field_custom_names=config.get('field_custom_names')
field_custom_names=config.get('field_custom_names'),
has_supplement=has_supplement
)
print(f"[日报生成] Excel文件已生成: {file_path}")
@@ -530,13 +539,14 @@ 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, field_custom_names=None):
id_name_maps=None, field_custom_names=None, has_supplement=False):
"""
生成Excel文件
Args:
id_name_maps: ID到名称的映射字典,格式为 {field_name: {id_value: name_value}}
field_custom_names: 字段自定义名头字典,格式为 {field_key: custom_name}
has_supplement: 是否有补单记录
Returns:
str: 文件路径
@@ -547,9 +557,17 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
reports_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'public', 'reports')
os.makedirs(reports_dir, exist_ok=True)
# 生成文件名
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f'daily_report_{config_name}_{split_name}_{timestamp}.xlsx'
# 生成文件名 - 格式:配置名称_几月几日消费记录.xlsx
# 从 end_time 提取日期(格式:2026-07-13 08:00:00)
try:
end_dt = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
date_str = f'{end_dt.month}月{end_dt.day}日'
except:
date_str = datetime.now().strftime('%m月%d日')
# 如果有补单,添加标记
supplement_suffix = '_有补单' if has_supplement else ''
filename = f'{config_name}_{date_str}消费记录{supplement_suffix}.xlsx'
file_path = os.path.join(reports_dir, filename)
# 创建工作簿

View File

@@ -351,6 +351,27 @@
border: 1px solid #bee5eb;
}
.checkbox-item.required-field {
background: #fff3cd;
border: 1px solid #ffc107;
}
.checkbox-item.required-field:hover {
background: #fff3cd;
cursor: default;
}
.required-badge {
display: inline-block;
padding: 2px 6px;
background: #ffc107;
color: #000;
border-radius: 3px;
font-size: 11px;
font-weight: 500;
margin-left: 4px;
}
.checkbox-item input[type="checkbox"] {
width: 16px;
height: 16px;
@@ -1177,14 +1198,19 @@
const fieldsList = document.getElementById('fields-list');
const sumFieldsList = document.getElementById('sum-fields-list');
fieldsList.innerHTML = allFields.map(field => `
<div class="checkbox-item ${selectedFields.includes(field.key) ? 'checked' : ''}" onclick="toggleCheckboxItem(this)">
<input type="checkbox" value="${field.key}"
${selectedFields.includes(field.key) ? 'checked' : ''}
onchange="onFieldCheckboxChange(this)">
<label>${field.display}</label>
</div>
`).join('');
fieldsList.innerHTML = allFields.map(field => {
const isSelected = selectedFields.includes(field.key);
const isRequired = field.key === 'charge_degree'; // 充电量为必选字段
return `
<div class="checkbox-item ${isSelected ? 'checked' : ''} ${isRequired ? 'required-field' : ''}" onclick="${isRequired ? '' : 'toggleCheckboxItem(this)'}">
<input type="checkbox" value="${field.key}"
${isSelected ? 'checked' : ''}
${isRequired ? 'disabled checked' : ''}
onchange="onFieldCheckboxChange(this)">
<label>${field.display}${isRequired ? ' <span class="required-badge">必选</span>' : ''}</label>
</div>
`;
}).join('');
// 初始化求和字段列表(只显示已选字段中的可求和字段)
refreshSumFieldsList(selectedFields, sumFields);
@@ -1201,6 +1227,12 @@
// 字段 checkbox 变化时更新求和字段列表和已选字段顺序
function onFieldCheckboxChange(cb) {
// 防止取消选择必选字段(充电量)
if (cb.value === 'charge_degree' && !cb.checked) {
cb.checked = true;
return;
}
const item = cb.closest('.checkbox-item');
if (item) item.classList.toggle('checked', cb.checked);
@@ -1651,6 +1683,11 @@
return;
}
// 确保充电量为必选字段
if (!selectedFields.includes('charge_degree')) {
selectedFields.push('charge_degree');
}
// 验证合并特来电配置
if (mergeTelecom && splitType !== 'company_id') {
alert('合并特来电数据仅支持按企业拆分');