Kamixitong/app/api/settings.py
2025-12-12 11:35:14 +08:00

245 lines
9.7 KiB
Python

from flask import request, jsonify, current_app
from . import api_bp
from .license import require_admin
import os
# 系统设置配置项映射
CONFIG_MAPPING = {
# 基本设置
'site_name': 'SITE_NAME',
'admin_email': 'ADMIN_EMAIL',
'frontend_domain': 'FRONTEND_DOMAIN',
'max_failed_attempts': 'MAX_FAILED_ATTEMPTS',
'lockout_minutes': 'LOCKOUT_MINUTES',
'max_unbind_times': 'MAX_UNBIND_TIMES',
'auth_secret_key': 'AUTH_SECRET_KEY',
# 安全设置
'secret_key': 'SECRET_KEY',
'session_cookie_secure': 'SESSION_COOKIE_SECURE',
'session_cookie_httponly': 'SESSION_COOKIE_HTTPONLY',
'session_cookie_samesite': 'SESSION_COOKIE_SAMESITE',
# 卡密设置
'license_key_length': 'LICENSE_KEY_LENGTH',
'license_key_prefix': 'LICENSE_KEY_PREFIX',
'trial_prefix': 'TRIAL_PREFIX',
'offline_cache_days': 'OFFLINE_CACHE_DAYS',
# API设置
'api_version': 'API_VERSION',
'items_per_page': 'ITEMS_PER_PAGE',
# 文件上传设置
'max_content_length': 'MAX_CONTENT_LENGTH',
'upload_folder': 'UPLOAD_FOLDER',
# 会话设置
'session_lifetime_hours': 'SESSION_LIFETIME_HOURS',
# 记住我设置
'remember_cookie_duration': 'REMEMBER_COOKIE_DURATION_DAYS', # 特殊处理
'remember_cookie_secure': 'REMEMBER_COOKIE_SECURE',
'remember_cookie_httponly': 'REMEMBER_COOKIE_HTTPONLY',
'remember_cookie_samesite': 'REMEMBER_COOKIE_SAMESITE',
# 日志设置
'log_level': 'LOG_LEVEL',
# 支付设置
'alipay_app_id': 'ALIPAY_APP_ID',
'alipay_private_key': 'ALIPAY_PRIVATE_KEY',
'alipay_public_key': 'ALIPAY_PUBLIC_KEY',
'alipay_alipay_public_key': 'ALIPAY_ALIPAY_PUBLIC_KEY',
'alipay_gateway': 'ALIPAY_GATEWAY',
'alipay_sign_type': 'ALIPAY_SIGN_TYPE',
'alipay_charset': 'ALIPAY_CHARSET',
'alipay_version': 'ALIPAY_VERSION',
'alipay_notify_url': 'ALIPAY_NOTIFY_URL',
'alipay_return_url': 'ALIPAY_RETURN_URL',
'alipay_timeout_express': 'ALIPAY_TIMEOUT_EXPRESS',
'payment_enabled': 'PAYMENT_ENABLED'
}
@require_admin
@api_bp.route('/settings/test-payment', methods=['POST'])
def test_payment():
"""测试支付功能"""
try:
# 获取当前配置
config = current_app.config
# 检查支付功能是否启用
if not config.get('PAYMENT_ENABLED'):
return jsonify({'success': False, 'message': '支付功能未启用'}), 400
# 检查支付宝配置
required_configs = ['ALIPAY_APP_ID', 'ALIPAY_PRIVATE_KEY', 'ALIPAY_PUBLIC_KEY', 'ALIPAY_ALIPAY_PUBLIC_KEY']
missing_configs = [cfg for cfg in required_configs if not config.get(cfg)]
if missing_configs:
return jsonify({'success': False, 'message': f'缺少支付宝配置: {", ".join(missing_configs)}'}), 400
# 创建测试订单
try:
from app.utils.alipay import AlipayHelper
from app.models import Order
import time
import random
# 初始化支付宝助手
alipay_helper = AlipayHelper(current_app)
# 生成测试订单号
test_order_number = f"TEST{int(time.time())}{random.randint(100, 999)}"
# 创建支付链接
notify_url = config.get('ALIPAY_NOTIFY_URL') or f"{request.url_root.strip('/')}/api/v1/pay/alipay/notify"
return_url = config.get('ALIPAY_RETURN_URL') or f"{request.url_root.strip('/')}/payment/result"
payment_url = alipay_helper.create_payment_url(
order_number=test_order_number,
amount=0.01, # 测试金额
subject='支付功能测试',
notify_url=notify_url,
return_url=return_url
)
current_app.logger.info(f"支付功能测试成功,订单号: {test_order_number}")
return jsonify({
'success': True,
'message': '支付功能测试成功!',
'payment_url': payment_url,
'order_number': test_order_number
})
except Exception as e:
current_app.logger.error(f"创建支付链接失败: {str(e)}")
return jsonify({'success': False, 'message': f'创建支付链接失败: {str(e)}'}), 400
except Exception as e:
current_app.logger.error(f"测试支付功能失败: {str(e)}")
return jsonify({'success': False, 'message': '服务器内部错误'}), 500
@require_admin
@api_bp.route('/settings/test-alipay', methods=['POST'])
def test_alipay_config():
"""测试支付宝配置"""
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'message': '请求数据为空'}), 400
# 获取配置参数
alipay_app_id = data.get('alipay_app_id')
alipay_private_key = data.get('alipay_private_key')
alipay_public_key = data.get('alipay_public_key')
alipay_alipay_public_key = data.get('alipay_alipay_public_key')
alipay_gateway = data.get('alipay_gateway', 'https://openapi.alipay.com/gateway.do')
# 验证必填项
if not all([alipay_app_id, alipay_private_key, alipay_public_key, alipay_alipay_public_key]):
return jsonify({'success': False, 'message': '请填写完整的支付宝配置信息'}), 400
# 验证基本参数
if not alipay_app_id or len(alipay_app_id) < 10:
return jsonify({'success': False, 'message': '无效的APP_ID'}), 400
# 验证密钥格式
if 'BEGIN' not in alipay_private_key or 'END' not in alipay_private_key:
return jsonify({'success': False, 'message': '私钥格式不正确'}), 400
if 'BEGIN' not in alipay_public_key or 'END' not in alipay_public_key:
return jsonify({'success': False, 'message': '公钥格式不正确'}), 400
if 'BEGIN' not in alipay_alipay_public_key or 'END' not in alipay_alipay_public_key:
return jsonify({'success': False, 'message': '支付宝公钥格式不正确'}), 400
# 如果所有验证通过,返回成功
return jsonify({
'success': True,
'message': '支付宝配置测试成功!',
'details': {
'app_id': alipay_app_id,
'gateway': alipay_gateway,
'sign_type': 'RSA2'
}
})
except Exception as e:
current_app.logger.error(f"测试支付宝配置失败: {str(e)}")
return jsonify({'success': False, 'message': '服务器内部错误'}), 500
@require_admin
@api_bp.route('/settings', methods=['POST'])
def save_settings():
"""保存系统设置"""
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'message': '请求数据为空'}), 400
# 获取当前应用配置
app_config = current_app.config
# 更新配置项
updated_configs = {}
for key, value in data.items():
if key in CONFIG_MAPPING:
config_key = CONFIG_MAPPING[key]
# 类型转换
if key in ['max_failed_attempts', 'lockout_minutes', 'max_unbind_times',
'license_key_length', 'offline_cache_days', 'items_per_page',
'session_lifetime_hours', 'remember_cookie_duration']:
value = int(value)
elif key in ['session_cookie_secure', 'session_cookie_httponly',
'remember_cookie_secure', 'remember_cookie_httponly']:
# 转换布尔值
value = value is True or value == 'True' or value == 'true'
elif key == 'max_content_length':
# 转换为字节
value = int(value) * 1024 * 1024
elif key == 'session_lifetime_hours':
# 转换为秒
value = int(value) * 3600
elif key in ['alipay_timeout_express']:
# 支付超时时间,转换为分钟
value = int(value)
elif key in ['payment_enabled']:
# 支付开关
value = value is True or value == 'True' or value == 'true'
elif key in ['alipay_sign_type', 'alipay_charset', 'alipay_version']:
# 支付相关字符串配置
pass # 保持原值
# 注意:密钥类配置(私钥、公钥等)不进行类型转换,直接保存
# 更新配置
app_config[config_key] = value
updated_configs[config_key] = value
# 特殊处理会话生命周期
if 'SESSION_LIFETIME_HOURS' in updated_configs:
from datetime import timedelta
app_config['PERMANENT_SESSION_LIFETIME'] = timedelta(seconds=updated_configs['SESSION_LIFETIME_HOURS'])
# 特殊处理记住我持续时间
if 'REMEMBER_COOKIE_DURATION_DAYS' in updated_configs:
from datetime import timedelta
app_config['REMEMBER_COOKIE_DURATION'] = timedelta(days=updated_configs['REMEMBER_COOKIE_DURATION_DAYS'])
# 特殊处理SECRET_KEY
if 'SECRET_KEY' in updated_configs:
# 更新应用的SECRET_KEY
app_config['SECRET_KEY'] = updated_configs['SECRET_KEY']
return jsonify({
'success': True,
'message': '设置保存成功',
'updated_configs': updated_configs
})
except Exception as e:
current_app.logger.error(f"保存设置失败: {str(e)}")
return jsonify({'success': False, 'message': '服务器内部错误'}), 500