2026-07-14 14:24:21 +08:00
|
|
|
|
"""
|
|
|
|
|
|
求和数据管理 API
|
|
|
|
|
|
"""
|
|
|
|
|
|
from flask import request, jsonify
|
|
|
|
|
|
from lib.sum_data_collector import (
|
|
|
|
|
|
collect_sum_data_from_history,
|
|
|
|
|
|
get_sum_data_list,
|
|
|
|
|
|
add_sum_data,
|
|
|
|
|
|
update_sum_data,
|
|
|
|
|
|
delete_sum_data,
|
2026-07-14 14:39:38 +08:00
|
|
|
|
batch_delete_sum_data,
|
2026-07-14 16:05:43 +08:00
|
|
|
|
get_monthly_charge_degree_total,
|
|
|
|
|
|
export_sum_data_to_excel
|
2026-07-14 14:24:21 +08:00
|
|
|
|
)
|
2026-07-15 16:01:06 +08:00
|
|
|
|
from lib.logger import log_info, log_error, log_warning
|
2026-07-14 14:24:21 +08:00
|
|
|
|
from . import sum_data_bp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/collect', methods=['POST'])
|
|
|
|
|
|
def collect_sum_data():
|
|
|
|
|
|
"""从历史记录采集求和数据"""
|
|
|
|
|
|
try:
|
2026-07-21 15:21:29 +08:00
|
|
|
|
data = request.get_json(silent=True) or {}
|
2026-07-14 14:24:21 +08:00
|
|
|
|
history_id = data.get('history_id')
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 采集求和数据,历史记录ID: {history_id or "全部"}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
|
|
|
|
|
|
result = collect_sum_data_from_history(history_id)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 采集成功: {result["message"]}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_warning(f'[求和数据API] 采集失败: {result["message"]}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 采集异常: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data', methods=['GET'])
|
|
|
|
|
|
def list_sum_data():
|
|
|
|
|
|
"""查询求和数据列表"""
|
|
|
|
|
|
try:
|
2026-07-23 15:17:07 +08:00
|
|
|
|
page_param = request.args.get('page')
|
|
|
|
|
|
page = int(page_param) if page_param else None
|
2026-07-14 14:24:21 +08:00
|
|
|
|
page_size = int(request.args.get('page_size', 20))
|
2026-07-14 16:05:43 +08:00
|
|
|
|
start_date = request.args.get('start_date')
|
|
|
|
|
|
end_date = request.args.get('end_date')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
config_id = request.args.get('config_id')
|
|
|
|
|
|
config_name = request.args.get('config_name')
|
|
|
|
|
|
sum_field_key = request.args.get('sum_field_key')
|
|
|
|
|
|
data_source = request.args.get('data_source')
|
2026-07-23 15:17:07 +08:00
|
|
|
|
log_info(f'[求和数据API] 查询求和数据列表,page={page}, page_size={page_size}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
|
|
|
|
|
|
result = get_sum_data_list(
|
|
|
|
|
|
page=page,
|
|
|
|
|
|
page_size=page_size,
|
2026-07-14 16:05:43 +08:00
|
|
|
|
start_date=start_date,
|
|
|
|
|
|
end_date=end_date,
|
2026-07-14 14:24:21 +08:00
|
|
|
|
config_id=config_id,
|
|
|
|
|
|
config_name=config_name,
|
|
|
|
|
|
sum_field_key=sum_field_key,
|
|
|
|
|
|
data_source=data_source
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 查询成功,共{result["data"]["total"]}条记录', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 查询求和数据列表失败: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data', methods=['POST'])
|
|
|
|
|
|
def create_sum_data():
|
|
|
|
|
|
"""手动添加求和数据"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
data = request.json
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info('[求和数据API] 手动添加求和数据', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
result = add_sum_data(data)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 添加成功,ID: {result.get("id", "")}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 添加求和数据失败: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/<int:sum_data_id>', methods=['PUT'])
|
|
|
|
|
|
def update_sum_data_api(sum_data_id):
|
|
|
|
|
|
"""更新求和数据"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
data = request.json
|
2026-07-23 14:57:29 +08:00
|
|
|
|
log_info(f'[求和数据API] 更新求和数据,ID: {sum_data_id}, 请求数据: {data}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
result = update_sum_data(sum_data_id, data)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 更新成功,ID: {sum_data_id}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
2026-07-23 14:57:29 +08:00
|
|
|
|
log_warning(f'[求和数据API] 更新失败,ID: {sum_data_id}, 原因: {result["message"]}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 更新求和数据失败: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/<int:sum_data_id>', methods=['DELETE'])
|
|
|
|
|
|
def delete_sum_data_api(sum_data_id):
|
|
|
|
|
|
"""删除求和数据"""
|
|
|
|
|
|
try:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 删除求和数据,ID: {sum_data_id}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
result = delete_sum_data(sum_data_id)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 删除成功,ID: {sum_data_id}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 删除求和数据失败: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/batch-delete', methods=['POST'])
|
|
|
|
|
|
def batch_delete_sum_data_api():
|
|
|
|
|
|
"""批量删除求和数据"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
data = request.json
|
|
|
|
|
|
ids = data.get('ids', [])
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 批量删除求和数据,数量: {len(ids)}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
if not ids:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_warning('[求和数据API] 批量删除失败:未选择记录', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': '请选择要删除的记录'}), 400
|
|
|
|
|
|
|
|
|
|
|
|
result = batch_delete_sum_data(ids)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 批量删除成功,{result["message"]}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 批量删除求和数据失败: {e}', 'api')
|
2026-07-14 14:24:21 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
2026-07-14 14:39:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-07-23 14:57:29 +08:00
|
|
|
|
@sum_data_bp.route('/sum-data/batch-query', methods=['POST'])
|
|
|
|
|
|
def batch_query_sum_data():
|
|
|
|
|
|
"""根据ID列表批量查询求和数据"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
data = request.json
|
|
|
|
|
|
ids = data.get('ids', [])
|
|
|
|
|
|
log_info(f'[求和数据API] 批量查询求和数据,ID数量: {len(ids)}', 'api')
|
|
|
|
|
|
|
|
|
|
|
|
if not ids:
|
|
|
|
|
|
return jsonify({'success': False, 'message': '请提供ID列表'}), 400
|
|
|
|
|
|
|
|
|
|
|
|
from lib.db import execute_query
|
|
|
|
|
|
|
|
|
|
|
|
placeholders = ','.join(['%s'] * len(ids))
|
|
|
|
|
|
sql = f'SELECT * FROM t_daily_report_sum_data WHERE id IN ({placeholders})'
|
|
|
|
|
|
|
|
|
|
|
|
result = execute_query(sql, tuple(ids))
|
|
|
|
|
|
|
|
|
|
|
|
return jsonify({
|
|
|
|
|
|
'success': True,
|
|
|
|
|
|
'data': result
|
|
|
|
|
|
})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
log_error(f'[求和数据API] 批量查询求和数据失败: {e}', 'api')
|
|
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/batch-add', methods=['POST'])
|
|
|
|
|
|
def batch_add_sum_data():
|
|
|
|
|
|
"""批量添加求和数据"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
data = request.json
|
|
|
|
|
|
fields = data.get('fields', [])
|
|
|
|
|
|
log_info(f'[求和数据API] 批量添加求和数据,字段数量: {len(fields)}', 'api')
|
|
|
|
|
|
|
|
|
|
|
|
if not fields:
|
|
|
|
|
|
return jsonify({'success': False, 'message': '请至少添加一个字段'}), 400
|
|
|
|
|
|
|
|
|
|
|
|
from lib.sum_data_collector import batch_add_sum_data
|
|
|
|
|
|
|
|
|
|
|
|
result = batch_add_sum_data(data)
|
|
|
|
|
|
if result['success']:
|
|
|
|
|
|
log_info(f'[求和数据API] 批量添加成功,添加{result["count"]}条记录', 'api')
|
|
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
log_error(f'[求和数据API] 批量添加求和数据失败: {e}', 'api')
|
|
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-07-14 14:39:38 +08:00
|
|
|
|
@sum_data_bp.route('/sum-data/monthly-total', methods=['GET'])
|
|
|
|
|
|
def monthly_charge_degree_total():
|
|
|
|
|
|
"""获取指定配置当月充电电量累计(从sum_data表查询,对账后的数据)
|
|
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
|
config_id: 配置ID(可选,不传则查所有配置总和)
|
|
|
|
|
|
month: 月份,格式 YYYY-MM(可选,默认当月)
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
config_id = request.args.get('config_id')
|
|
|
|
|
|
month = request.args.get('month')
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 查询月度累计,配置ID: {config_id or "全部"},月份: {month or "当月"}', 'api')
|
2026-07-14 14:39:38 +08:00
|
|
|
|
|
|
|
|
|
|
result = get_monthly_charge_degree_total(config_id, month)
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 查询成功,累计电量: {result["data"]["total_degree"]} kWh', 'api')
|
2026-07-14 14:39:38 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 查询月度累计失败: {e}', 'api')
|
2026-07-14 14:39:38 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|
2026-07-14 16:05:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@sum_data_bp.route('/sum-data/export', methods=['GET'])
|
|
|
|
|
|
def export_sum_data():
|
|
|
|
|
|
"""导出求和数据为Excel
|
|
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
|
start_date: 开始日期(可选)
|
|
|
|
|
|
end_date: 结束日期(可选)
|
|
|
|
|
|
config_id: 配置ID(可选)
|
|
|
|
|
|
data_source: 数据来源(可选)
|
|
|
|
|
|
keyword: 配置名称关键词(可选)
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
start_date = request.args.get('start_date')
|
|
|
|
|
|
end_date = request.args.get('end_date')
|
|
|
|
|
|
config_id = request.args.get('config_id')
|
|
|
|
|
|
data_source = request.args.get('data_source')
|
|
|
|
|
|
keyword = request.args.get('keyword')
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 导出求和数据,日期范围: {start_date or "开始"} ~ {end_date or "结束"}', 'api')
|
2026-07-14 16:05:43 +08:00
|
|
|
|
|
|
|
|
|
|
result = export_sum_data_to_excel(
|
|
|
|
|
|
start_date=start_date,
|
|
|
|
|
|
end_date=end_date,
|
|
|
|
|
|
config_id=config_id,
|
|
|
|
|
|
data_source=data_source,
|
|
|
|
|
|
keyword=keyword
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if result['success']:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_info(f'[求和数据API] 导出成功,共{result.get("total", 0)}条记录', 'api')
|
2026-07-14 16:05:43 +08:00
|
|
|
|
return jsonify(result)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify(result), 400
|
|
|
|
|
|
except Exception as e:
|
2026-07-15 16:01:06 +08:00
|
|
|
|
log_error(f'[求和数据API] 导出求和数据失败: {e}', 'api')
|
2026-07-14 16:05:43 +08:00
|
|
|
|
return jsonify({'success': False, 'message': str(e)}), 500
|