Files
ai_wht_B/ver_2512212119/flask_wht_server_api.py
“shengyudong” 5a384b694e 2026-1-6
2026-01-06 14:18:39 +08:00

234 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
图文动态批量生产系统 v2.0
Flask后端API服务器 - 总入口
"""
from flask import Flask, request, jsonify, redirect
from flask_cors import CORS
import logging
import time
import os
from datetime import datetime, timedelta
from logging.handlers import TimedRotatingFileHandler
import json # Added for json.dumps
# 导入统一日志配置
from log_config import setup_article_server_logger
# 导入数据库配置
from database_config import get_db_manager, DB_CONFIG
# 导入各个接口模块
from auth_routes import auth_bp
from user_routes import user_bp
from log_routes import log_bp
from enterprise_routes import enterprise_bp
from employee_routes import employee_bp
from product_routes import product_bp
from image_routes import image_bp
from prompt_routes import prompt_bp
from article_routes import article_bp
from statistics_routes import statistics_bp
from dashboard_routes import dashboard_bp
from author_routes import author_bp
# 导入认证工具
from auth_utils import AuthUtils, require_auth
# 创建Flask应用
app = Flask(__name__, static_folder='public', static_url_path='')
# 初始化日志系统
logger = setup_article_server_logger()
# 配置CORS - 允许所有域名的跨域请求
CORS(app,
origins=["http://127.0.0.1:8324", "http://localhost:8324", "http://127.0.0.1:3000", "http://localhost:3000", "*"],
methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Content-Type", "Authorization", "Accept", "X-Requested-With"],
supports_credentials=True,
max_age=3600)
# 注册蓝图
app.register_blueprint(auth_bp)
app.register_blueprint(user_bp)
app.register_blueprint(log_bp)
app.register_blueprint(enterprise_bp)
app.register_blueprint(employee_bp)
app.register_blueprint(product_bp)
app.register_blueprint(image_bp)
app.register_blueprint(prompt_bp)
app.register_blueprint(article_bp)
app.register_blueprint(statistics_bp)
app.register_blueprint(dashboard_bp)
app.register_blueprint(author_bp)
# 请求前拦截器 - 记录所有API访问
@app.before_request
def log_request_info():
"""记录每个请求的基本信息"""
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
user_agent = request.headers.get('User-Agent', '未知')
logger.info(f"[API访问] {request.method} {request.path} - IP: {client_ip} - User-Agent: {user_agent[:100]}")
# 记录请求参数GET请求
if request.args:
logger.debug(f"[请求参数] GET参数: {dict(request.args)}")
# CORS已经通过CORS(app)配置不需要额外的OPTIONS处理
# 请求后拦截器 - 记录响应状态
@app.after_request
def log_response_info(response):
"""记录响应状态"""
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
logger.info(f"[API响应] {request.method} {request.path} - IP: {client_ip} - 状态码: {response.status_code}")
return response
@app.route('/health', methods=['GET'])
def health_check():
"""健康检查接口"""
try:
# 检查数据库连接
db_manager = get_db_manager()
db_manager.execute_query("SELECT 1")
return jsonify({
'code': 200,
'message': '服务正常',
'data': {
'status': 'healthy',
'timestamp': int(datetime.now().timestamp() * 1000),
'version': '2.0'
}
})
except Exception as e:
logger.error(f"健康检查失败: {e}")
return jsonify({
'code': 500,
'message': '服务异常',
'data': {
'status': 'unhealthy',
'error': str(e),
'timestamp': int(datetime.now().timestamp() * 1000)
}
}), 500
@app.route('/', methods=['GET'])
def index():
"""根路径接口"""
return jsonify({
'code': 200,
'message': '万花筒API服务正常运行',
'data': {
'version': '1.0',
'service': 'wht_api'
}
})
@app.errorhandler(404)
def not_found(error):
"""404错误处理"""
return jsonify({
'code': 404,
'message': '接口不存在',
'data': None,
'timestamp': int(datetime.now().timestamp() * 1000)
}), 404
@app.errorhandler(405)
def method_not_allowed(error):
"""405错误处理"""
return jsonify({
'code': 405,
'message': '请求方法不允许',
'data': None,
'timestamp': int(datetime.now().timestamp() * 1000)
}), 405
@app.errorhandler(500)
def internal_error(error):
"""500错误处理"""
import traceback
error_traceback = traceback.format_exc()
logger.error(f"服务器内部错误: {error}")
logger.error(f"错误堆栈: {error_traceback}")
return jsonify({
'code': 500,
'message': '服务器内部错误',
'data': None,
'timestamp': int(datetime.now().timestamp() * 1000)
}), 500
# 开发环境启动入口
if __name__ == '__main__':
print("=" * 60)
print("万花筒API服务 v1.0 启动中...")
print("⚠️ 警告: 当前使用开发服务器,不建议在生产环境中使用")
print("⚠️ 生产环境请使用: waitress 等WSGI服务器")
print("-" * 60)
print("服务地址: http://127.0.0.1:8216")
print("健康检查: http://127.0.0.1:8216/health")
print("-" * 60)
print("接口模块:")
print(" - 用户认证: /api/v1/auth")
print(" - 企业管理: /api/v1/enterprises")
print(" - 员工管理: /api/v1/employees")
print(" - 产品管理: /api/v1/products")
print(" - 图片库管理: /api/v1/images")
print(" - 提示词管理: /api/v1/prompts")
print(" - 文案库管理: /api/v1/articles")
print(" - 数据统计: /api/v1/statistics")
print(" - 工作台: /api/v1/dashboard")
print(" - 用户管理: /api/users")
print(" - 日志管理: /api/log")
print("-" * 60)
print("日志配置信息:")
print(f" 主日志文件: logs/article_server.log")
print(f" 错误日志文件: logs/article_error.log")
print(f" 日志切割: 每日午夜自动切割")
print(f" 日志保留: 主日志3天错误日志9天")
print("-" * 60)
print("数据库配置:")
print(f" 主机: 127.0.0.1:3306")
print(f" 数据库: ai_wht")
print(f" 用户: root")
print("-" * 60)
print("生产部署命令:")
print(" waitress-serve --host=0.0.0.0 --port=8216 flask_wht_server_api:app")
print("=" * 60)
try:
# 测试数据库连接
logger.info("测试数据库连接...")
db_manager = get_db_manager()
db_manager.execute_query("SELECT 1")
logger.info("数据库连接成功")
# 启动开发服务器
logger.warning("使用Flask开发服务器启动仅用于开发测试")
app.run(
host='0.0.0.0',
port=8216,
debug=False,
threaded=True
)
except KeyboardInterrupt:
logger.info("收到中断信号,正在关闭服务器...")
print("\n服务器已关闭")
except Exception as e:
logger.error(f"服务器启动失败: {str(e)}", exc_info=True)
print(f"服务器启动失败: {str(e)}")
finally:
logger.info("万花筒API服务已停止")
print("日志已保存到 logs/ 目录")
# 生产环境初始化(当作为模块导入时执行)
else:
logger.info('万花筒API服务模块已加载')