增加尖峰平谷找平功能,修改消息提示
This commit is contained in:
@@ -60,6 +60,13 @@ def create_config():
|
||||
show_custom_service_fee = 1 if data.get('show_custom_service_fee') else 0
|
||||
show_total_amount = 1 if data.get('show_total_amount') else 0
|
||||
total_amount_name = data.get('total_amount_name')
|
||||
# 找平电量开关:默认开启(1=开启,0=关闭)
|
||||
# 当数据中的'未在前端传递时,默认为1(开启),保持与历史配置的兼容性
|
||||
balance_electricity = data.get('balance_electricity')
|
||||
if balance_electricity is None:
|
||||
balance_electricity = 1
|
||||
else:
|
||||
balance_electricity = 1 if balance_electricity else 0
|
||||
|
||||
if not config_name or not split_type or not split_value:
|
||||
log_warning('[配置API] 创建配置失败:缺少必填字段', 'api')
|
||||
@@ -81,9 +88,9 @@ def create_config():
|
||||
(id, config_name, split_type, split_value, split_name, selected_fields,
|
||||
sum_fields, time_periods, merge_telecom, telecom_vehicle_no, field_custom_names,
|
||||
show_monthly_total, custom_service_fee_price, custom_service_fee_name,
|
||||
show_custom_service_fee, show_total_amount, total_amount_name,
|
||||
show_custom_service_fee, show_total_amount, total_amount_name, balance_electricity,
|
||||
is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 1, %s, NOW(), NOW())
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 1, %s, NOW(), NOW())
|
||||
"""
|
||||
|
||||
params = (
|
||||
@@ -104,6 +111,7 @@ def create_config():
|
||||
show_custom_service_fee,
|
||||
show_total_amount,
|
||||
total_amount_name if total_amount_name else None,
|
||||
balance_electricity,
|
||||
sort_order
|
||||
)
|
||||
|
||||
@@ -148,6 +156,12 @@ def update_config(config_id):
|
||||
show_custom_service_fee = 1 if data.get('show_custom_service_fee') else 0
|
||||
show_total_amount = 1 if data.get('show_total_amount') else 0
|
||||
total_amount_name = data.get('total_amount_name')
|
||||
# 找平电量开关:默认开启(1=开启,0=关闭)
|
||||
balance_electricity = data.get('balance_electricity')
|
||||
if balance_electricity is None:
|
||||
balance_electricity = 1
|
||||
else:
|
||||
balance_electricity = 1 if balance_electricity else 0
|
||||
|
||||
# 查询原配置,检查拆分是否变化
|
||||
old_configs = execute_query('SELECT * FROM t_daily_report_config WHERE id = %s', (config_id,))
|
||||
@@ -162,6 +176,7 @@ def update_config(config_id):
|
||||
merge_telecom = %s, telecom_vehicle_no = %s, field_custom_names = %s,
|
||||
show_monthly_total = %s, custom_service_fee_price = %s, custom_service_fee_name = %s,
|
||||
show_custom_service_fee = %s, show_total_amount = %s, total_amount_name = %s,
|
||||
balance_electricity = %s,
|
||||
update_time = NOW()
|
||||
WHERE id = %s
|
||||
"""
|
||||
@@ -183,6 +198,7 @@ def update_config(config_id):
|
||||
show_custom_service_fee,
|
||||
show_total_amount,
|
||||
total_amount_name if total_amount_name else None,
|
||||
balance_electricity,
|
||||
config_id
|
||||
)
|
||||
|
||||
@@ -257,8 +273,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, field_custom_names, show_monthly_total, custom_service_fee_price, custom_service_fee_name, show_custom_service_fee, show_total_amount, total_amount_name, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %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, show_monthly_total, custom_service_fee_price, custom_service_fee_name, show_custom_service_fee, show_total_amount, total_amount_name, balance_electricity, is_active, sort_order, create_time, update_time)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())''',
|
||||
(
|
||||
new_id,
|
||||
new_name,
|
||||
@@ -277,6 +293,8 @@ def copy_config(config_id):
|
||||
original.get('show_custom_service_fee', 0),
|
||||
original.get('show_total_amount', 0),
|
||||
original.get('total_amount_name'),
|
||||
# 找平电量:复制原配置的设置,若原配置无此字段(NULL)则默认开启(1)
|
||||
original.get('balance_electricity') if original.get('balance_electricity') is not None else 1,
|
||||
original['is_active'],
|
||||
sort_order
|
||||
)
|
||||
|
||||
@@ -182,6 +182,15 @@ def init_database_tables():
|
||||
"total_amount_name VARCHAR(100) NULL COMMENT '实收金额报表表头名称'",
|
||||
'total_amount_name'
|
||||
)
|
||||
|
||||
# 给配置表增加 balance_electricity 字段(是否找平电量)
|
||||
# 当尖+峰+平+谷之和不等于充电电量时,以充电电量为准进行找平
|
||||
# 找平顺序:谷 → 平 → 峰 → 尖(加到第一个有值的时段上)
|
||||
_add_column_if_not_exists(
|
||||
't_daily_report_config',
|
||||
"balance_electricity TINYINT NULL DEFAULT 1 COMMENT '是否找平电量(0=否,1=是)'",
|
||||
'balance_electricity'
|
||||
)
|
||||
|
||||
# 创建全局配置表
|
||||
create_global_config_table = """
|
||||
|
||||
@@ -285,6 +285,70 @@ def calculate_time_period_electricity(orders, time_periods_config):
|
||||
return result
|
||||
|
||||
|
||||
def balance_time_period_electricity(orders):
|
||||
"""
|
||||
找平分时段电量
|
||||
|
||||
正常情况下:充电电量(charge_degree) = 尖电量 + 峰电量 + 平电量 + 谷电量
|
||||
但平台导出数据时,四者之和可能不等于充电电量。
|
||||
本函数以充电电量(charge_degree)为准,将差额加到对应时段上。
|
||||
|
||||
找平原则(按优先级顺序):
|
||||
1. 有谷电量(>0) → 差额加到谷上
|
||||
2. 没谷有平电量(>0) → 差额加到平上
|
||||
3. 没平有峰电量(>0) → 差额加到峰上
|
||||
4. 都没有 → 差额加到尖上
|
||||
|
||||
Args:
|
||||
orders: 订单数据列表(会原地修改 sharp/peak/flat/valley_electricity 字段)
|
||||
|
||||
Returns:
|
||||
int: 实际找平的订单数
|
||||
"""
|
||||
balanced_count = 0
|
||||
|
||||
for order in orders:
|
||||
# 获取充电电量(作为基准)
|
||||
charge_degree = order.get('charge_degree')
|
||||
if charge_degree is None or charge_degree == '':
|
||||
continue
|
||||
|
||||
try:
|
||||
charge_degree = float(charge_degree)
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
|
||||
# 获取各时段电量
|
||||
sharp = float(order.get('sharp_electricity', 0) or 0)
|
||||
peak = float(order.get('peak_electricity', 0) or 0)
|
||||
flat = float(order.get('flat_electricity', 0) or 0)
|
||||
valley = float(order.get('valley_electricity', 0) or 0)
|
||||
|
||||
# 计算四时段之和
|
||||
period_sum = round(sharp + peak + flat + valley, 3)
|
||||
|
||||
# 计算差额
|
||||
diff = round(charge_degree - period_sum, 3)
|
||||
|
||||
# 如果差额为0,不需要找平
|
||||
if abs(diff) < 0.001:
|
||||
continue
|
||||
|
||||
# 按优先级找平:谷 → 平 → 峰 → 尖
|
||||
if valley > 0:
|
||||
order['valley_electricity'] = round(valley + diff, 3)
|
||||
elif flat > 0:
|
||||
order['flat_electricity'] = round(flat + diff, 3)
|
||||
elif peak > 0:
|
||||
order['peak_electricity'] = round(peak + diff, 3)
|
||||
else:
|
||||
order['sharp_electricity'] = round(sharp + diff, 3)
|
||||
|
||||
balanced_count += 1
|
||||
|
||||
return balanced_count
|
||||
|
||||
|
||||
def get_beijing_time():
|
||||
"""获取北京时间"""
|
||||
beijing_tz = pytz.timezone('Asia/Shanghai')
|
||||
@@ -592,6 +656,19 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
||||
|
||||
log_info(f"[日报生成] 已计算 {len(time_period_electricity)} 条订单的分时段电量", 'report')
|
||||
|
||||
# 找平分时段电量
|
||||
# 当配置开启了找平电量功能时,以充电电量(charge_degree)为准,
|
||||
# 将尖+峰+平+谷之和与充电电量的差额,按 谷→平→峰→尖 的优先级加到对应时段上
|
||||
balance_electricity_enabled = config.get('balance_electricity')
|
||||
# 兼容历史配置:NULL 或未设置时默认开启
|
||||
if balance_electricity_enabled is None:
|
||||
balance_electricity_enabled = 1
|
||||
|
||||
if balance_electricity_enabled == 1:
|
||||
balanced_count = balance_time_period_electricity(orders)
|
||||
if balanced_count > 0:
|
||||
log_info(f"[日报生成] 找平电量:共处理 {balanced_count} 条订单的分时段电量差额", 'report')
|
||||
|
||||
# 计算虚拟字段(自定义服务费、自定义实收总金额)并添加到订单数据中
|
||||
# 这样求和数据才能正确计算这些字段的总和
|
||||
has_custom_service_fee = config.get('custom_service_fee_price') is not None and str(config.get('custom_service_fee_price', '')).strip() != ''
|
||||
|
||||
Reference in New Issue
Block a user