Files
selfrelease 79e869eeda fix: 修复外部因素数据源 - 北向资金改为南向资金,修复P0-P7全部外部因素
- P0资金面:DB数据过期时用麦蕊API获取资金流向
- P1市场情绪:去掉turnover字段依赖(DB无此字段)
- P2南向资金:北向实时数据已停公布,改用南向资金(港股通)替代
- P3美股:用腾讯财经API替代失效的AKShare接口
- P4大宗商品:用腾讯财经API替代,修复var_name解析
- P7汇率:用新浪财经API替代失效的AKShare接口
- 修复评分详情API技术得分硬编码问题
- 前端传入tech_score参数确保明细与列表分数一致
2026-07-18 16:45:58 +08:00

104 lines
2.8 KiB
Python
Raw Permalink 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.
"""
股票投资分析系统 - 主应用入口
"""
from flask import Flask, render_template, jsonify
from flask_cors import CORS
from config import Config
# 初始化配置
Config.init_app()
# 创建Flask应用
app = Flask(__name__, template_folder='templates', static_folder='static')
app.config['SECRET_KEY'] = Config.SECRET_KEY
CORS(app, supports_credentials=True)
# 初始化数据库连接池
from db import init_db_pool
init_db_pool()
# 注册路由蓝图
from routes.auth import bp as auth_bp
from routes.trades import bp as trades_bp
from routes.watchlist import bp as watchlist_bp
from routes.analysis import bp as analysis_bp
from routes.market import bp as market_bp
from routes.sim_trade import bp as sim_trade_bp
from routes.admin import bp as admin_bp
from routes.smart_trade import bp as smart_trade_bp
app.register_blueprint(auth_bp)
app.register_blueprint(trades_bp)
app.register_blueprint(watchlist_bp)
app.register_blueprint(analysis_bp)
app.register_blueprint(market_bp)
app.register_blueprint(sim_trade_bp)
app.register_blueprint(admin_bp)
app.register_blueprint(smart_trade_bp)
# ========== 基础路由 ==========
@app.route('/')
def index():
"""首页"""
return render_template('index.html')
@app.route('/api/health', methods=['GET'])
def health():
"""健康检查"""
return jsonify({'status': 'ok', 'message': '服务运行正常'})
# ========== 静态文件安全 ==========
@app.route('/robots.txt')
def robots():
return "User-agent: *\nDisallow: /api/\nDisallow: /admin\n", 200, {'Content-Type': 'text/plain'}
@app.route('/.env')
def block_env():
from flask import abort
abort(404)
# ========== 启动 ==========
_scheduler_started = False
def _start_scheduler_once():
"""确保调度器只启动一次(兼容 gunicorn preload + Flask dev reloader"""
global _scheduler_started
if _scheduler_started:
return
_scheduler_started = True
from services.scheduler import start_scheduler
start_scheduler()
# 启动时预热市场级外部因素缓存(后台线程,不阻塞启动)
import threading
def _preheat():
try:
from services.score_engine import precompute_market_factors
precompute_market_factors()
except Exception as e:
print(f"[启动] 外部因素预热失败: {e}")
threading.Thread(target=_preheat, daemon=True).start()
if __name__ == '__main__':
print("=" * 60)
print("股票投资分析系统启动")
print("=" * 60)
print(f"Web界面: http://localhost:{Config.PORT}")
print(f"API地址: http://localhost:{Config.PORT}/api/")
print(f"健康检查: http://localhost:{Config.PORT}/api/health")
print("=" * 60)
_start_scheduler_once()
app.run(debug=True, host='0.0.0.0', port=Config.PORT)
else:
_start_scheduler_once()