refactor: 重构项目结构,按功能模块拆分文件
- 后端:将 app.py 拆分为 lib/api/ 目录下的多个蓝图模块 - config_api.py: 配置管理 API - entity_api.py: 实体管理 API - field_api.py: 字段列表 API - report_api.py: 日报生成和历史记录 API - init_api.py: 数据库初始化 API - download_api.py: 文件下载 API - 前端:将 index.html 拆分为多个文件 - static/css/style.css: CSS 样式 - static/js/common.js: 通用工具函数 - static/js/config.js: 配置管理 - static/js/entity.js: 实体管理 - static/js/report.js: 日报生成 - static/js/history.js: 历史记录 - 更新 app.py 使用蓝图注册 API - 创建 AGENTS.md 项目文档 Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 9894087
This commit is contained in:
257
lib/api/config_api.py
Normal file
257
lib/api/config_api.py
Normal file
@@ -0,0 +1,257 @@
|
||||
"""
|
||||
配置管理 API
|
||||
"""
|
||||
import json
|
||||
from datetime import datetime
|
||||
from flask import request, jsonify
|
||||
from lib.db import execute_query, execute_update, execute_insert
|
||||
from . import config_bp
|
||||
|
||||
|
||||
@config_bp.route('/config', methods=['GET'])
|
||||
def get_configs():
|
||||
"""获取所有配置"""
|
||||
try:
|
||||
configs = execute_query(
|
||||
'SELECT * FROM t_daily_report_config ORDER BY sort_order ASC, id DESC'
|
||||
)
|
||||
|
||||
# 解析 JSON 字段
|
||||
for config in configs:
|
||||
config['selected_fields'] = json.loads(config['selected_fields'])
|
||||
config['sum_fields'] = json.loads(config['sum_fields']) if config['sum_fields'] else []
|
||||
config['time_periods'] = json.loads(config['time_periods']) if config.get('time_periods') else {}
|
||||
|
||||
return jsonify({'success': True, 'data': configs})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config', methods=['POST'])
|
||||
def create_config():
|
||||
"""创建配置"""
|
||||
try:
|
||||
data = request.json
|
||||
config_name = data.get('config_name')
|
||||
split_type = data.get('split_type')
|
||||
split_value = data.get('split_value')
|
||||
split_name = data.get('split_name', '')
|
||||
selected_fields = data.get('selected_fields', [])
|
||||
sum_fields = data.get('sum_fields', [])
|
||||
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
|
||||
|
||||
if not selected_fields:
|
||||
return jsonify({'success': False, 'message': '请至少选择一个字段'}), 400
|
||||
|
||||
# 生成 ID
|
||||
config_id = int(datetime.now().timestamp() * 1000)
|
||||
|
||||
# 获取最大排序值
|
||||
max_sort = execute_query('SELECT MAX(sort_order) as max_sort FROM t_daily_report_config')
|
||||
sort_order = (max_sort[0]['max_sort'] or 0) + 1
|
||||
|
||||
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, 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 = (
|
||||
config_id,
|
||||
config_name,
|
||||
split_type,
|
||||
split_value,
|
||||
split_name,
|
||||
json.dumps(selected_fields, ensure_ascii=False),
|
||||
json.dumps(sum_fields, ensure_ascii=False),
|
||||
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
|
||||
)
|
||||
|
||||
execute_insert(sql, params)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '配置创建成功',
|
||||
'data': {'id': config_id}
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config/<int:config_id>', methods=['PUT'])
|
||||
def update_config(config_id):
|
||||
"""更新配置"""
|
||||
try:
|
||||
data = request.json
|
||||
config_name = data.get('config_name')
|
||||
split_type = data.get('split_type')
|
||||
split_value = data.get('split_value')
|
||||
split_name = data.get('split_name', '')
|
||||
selected_fields = data.get('selected_fields', [])
|
||||
sum_fields = data.get('sum_fields', [])
|
||||
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, field_custom_names = %s, update_time = NOW()
|
||||
WHERE id = %s
|
||||
"""
|
||||
|
||||
params = (
|
||||
config_name,
|
||||
split_type,
|
||||
split_value,
|
||||
split_name,
|
||||
json.dumps(selected_fields, ensure_ascii=False),
|
||||
json.dumps(sum_fields, ensure_ascii=False),
|
||||
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
|
||||
)
|
||||
|
||||
execute_update(sql, params)
|
||||
|
||||
return jsonify({'success': True, 'message': '配置更新成功'})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config/<int:config_id>', methods=['DELETE'])
|
||||
def delete_config(config_id):
|
||||
"""删除配置"""
|
||||
try:
|
||||
execute_update('DELETE FROM t_daily_report_config WHERE id = %s', (config_id,))
|
||||
return jsonify({'success': True, 'message': '配置删除成功'})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config/<int:config_id>/copy', methods=['POST'])
|
||||
def copy_config(config_id):
|
||||
"""复制配置"""
|
||||
try:
|
||||
# 获取原配置
|
||||
configs = execute_query('SELECT * FROM t_daily_report_config WHERE id = %s', (config_id,))
|
||||
if not configs:
|
||||
return jsonify({'success': False, 'message': '原配置不存在'}), 404
|
||||
|
||||
original = configs[0]
|
||||
|
||||
# 生成新 ID 和新名称
|
||||
new_id = int(datetime.now().timestamp() * 1000)
|
||||
new_name = f"{original['config_name']}_副本"
|
||||
|
||||
# 获取最大排序值
|
||||
max_sort = execute_query('SELECT MAX(sort_order) as max_sort FROM t_daily_report_config')
|
||||
sort_order = (max_sort[0]['max_sort'] or 0) + 1
|
||||
|
||||
# 插入新配置
|
||||
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, 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,
|
||||
original['split_type'],
|
||||
original['split_value'],
|
||||
original['split_name'],
|
||||
original['selected_fields'],
|
||||
original.get('sum_fields', ''),
|
||||
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
|
||||
)
|
||||
)
|
||||
|
||||
return jsonify({'success': True, 'message': '配置复制成功', 'id': new_id})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config/<int:config_id>/toggle', methods=['POST'])
|
||||
def toggle_config(config_id):
|
||||
"""启用/禁用配置"""
|
||||
try:
|
||||
execute_update(
|
||||
'UPDATE t_daily_report_config SET is_active = NOT is_active, update_time = NOW() WHERE id = %s',
|
||||
(config_id,)
|
||||
)
|
||||
return jsonify({'success': True, 'message': '操作成功'})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
|
||||
|
||||
@config_bp.route('/config/<int:config_id>/move', methods=['POST'])
|
||||
def move_config(config_id):
|
||||
"""移动配置排序"""
|
||||
try:
|
||||
direction = request.json.get('direction') # up 或 down
|
||||
|
||||
# 获取当前配置
|
||||
current = execute_query(
|
||||
'SELECT sort_order FROM t_daily_report_config WHERE id = %s',
|
||||
(config_id,)
|
||||
)
|
||||
if not current:
|
||||
return jsonify({'success': False, 'message': '配置不存在'}), 404
|
||||
|
||||
current_order = current[0]['sort_order']
|
||||
|
||||
if direction == 'up':
|
||||
# 找到上一个配置
|
||||
prev = execute_query(
|
||||
'SELECT id, sort_order FROM t_daily_report_config WHERE sort_order < %s ORDER BY sort_order DESC LIMIT 1',
|
||||
(current_order,)
|
||||
)
|
||||
if prev:
|
||||
# 交换排序
|
||||
execute_update(
|
||||
'UPDATE t_daily_report_config SET sort_order = %s WHERE id = %s',
|
||||
(prev[0]['sort_order'], config_id)
|
||||
)
|
||||
execute_update(
|
||||
'UPDATE t_daily_report_config SET sort_order = %s WHERE id = %s',
|
||||
(current_order, prev[0]['id'])
|
||||
)
|
||||
elif direction == 'down':
|
||||
# 找到下一个配置
|
||||
next_config = execute_query(
|
||||
'SELECT id, sort_order FROM t_daily_report_config WHERE sort_order > %s ORDER BY sort_order ASC LIMIT 1',
|
||||
(current_order,)
|
||||
)
|
||||
if next_config:
|
||||
# 交换排序
|
||||
execute_update(
|
||||
'UPDATE t_daily_report_config SET sort_order = %s WHERE id = %s',
|
||||
(next_config[0]['sort_order'], config_id)
|
||||
)
|
||||
execute_update(
|
||||
'UPDATE t_daily_report_config SET sort_order = %s WHERE id = %s',
|
||||
(current_order, next_config[0]['id'])
|
||||
)
|
||||
|
||||
return jsonify({'success': True, 'message': '移动成功'})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': str(e)}), 500
|
||||
Reference in New Issue
Block a user