from flask import Blueprint, request, jsonify import json bp = Blueprint('industries', __name__, url_prefix='/api') @bp.route('/classifications', methods=['GET']) def get_classifications(): """获取行业分类""" try: # 模拟行业分类数据 classifications = [ { 'id': 1, 'name': '申万一级行业', 'description': '申万一级行业分类标准', 'levels': [ {'id': 1, 'name': '农林牧渔'}, {'id': 2, 'name': '采掘'}, {'id': 3, 'name': '化工'}, {'id': 4, 'name': '钢铁'}, {'id': 5, 'name': '有色金属'}, {'id': 6, 'name': '建筑材料'}, {'id': 7, 'name': '建筑装饰'}, {'id': 8, 'name': '电气设备'}, {'id': 9, 'name': '国防军工'}, {'id': 10, 'name': '汽车'}, {'id': 11, 'name': '家用电器'}, {'id': 12, 'name': '纺织服装'}, {'id': 13, 'name': '轻工制造'}, {'id': 14, 'name': '医药生物'}, {'id': 15, 'name': '公用事业'}, {'id': 16, 'name': '交通运输'}, {'id': 17, 'name': '房地产'}, {'id': 18, 'name': '商业贸易'}, {'id': 19, 'name': '休闲服务'}, {'id': 20, 'name': '银行'}, {'id': 21, 'name': '非银金融'}, {'id': 22, 'name': '综合'}, {'id': 23, 'name': '计算机'}, {'id': 24, 'name': '传媒'}, {'id': 25, 'name': '通信'}, {'id': 26, 'name': '电子'}, {'id': 27, 'name': '机械设备'}, {'id': 28, 'name': '食品饮料'} ] } ] return jsonify({ 'success': True, 'data': classifications }) except Exception as e: print(f"Error getting classifications: {e}") return jsonify({'success': False, 'error': str(e)}), 500 @bp.route('/levels', methods=['GET']) def get_industry_levels(): """获取行业层级""" try: classification_id = request.args.get('classification_id', '1') # 模拟行业层级数据 levels = [ { 'id': 1, 'name': '农林牧渔', 'code': '801010', 'description': '农业、林业、畜牧业、渔业', 'stock_count': 45, 'avg_change': 1.2, 'total_market_cap': 500000000000, 'sub_industries': [ {'id': 101, 'name': '种植业', 'stock_count': 20}, {'id': 102, 'name': '林业', 'stock_count': 8}, {'id': 103, 'name': '畜牧业', 'stock_count': 12}, {'id': 104, 'name': '渔业', 'stock_count': 5} ] }, { 'id': 2, 'name': '采掘', 'code': '801020', 'description': '煤炭、石油、天然气、有色金属矿采选', 'stock_count': 38, 'avg_change': 0.8, 'total_market_cap': 800000000000, 'sub_industries': [ {'id': 201, 'name': '煤炭开采', 'stock_count': 15}, {'id': 202, 'name': '石油开采', 'stock_count': 8}, {'id': 203, 'name': '有色金属矿采选', 'stock_count': 15} ] }, { 'id': 3, 'name': '化工', 'code': '801030', 'description': '化学原料、化学制品、化学纤维', 'stock_count': 156, 'avg_change': 1.5, 'total_market_cap': 1200000000000, 'sub_industries': [ {'id': 301, 'name': '化学原料', 'stock_count': 45}, {'id': 302, 'name': '化学制品', 'stock_count': 78}, {'id': 303, 'name': '化学纤维', 'stock_count': 33} ] }, { 'id': 4, 'name': '钢铁', 'code': '801040', 'description': '钢铁冶炼、钢铁制品', 'stock_count': 32, 'avg_change': 0.6, 'total_market_cap': 600000000000, 'sub_industries': [ {'id': 401, 'name': '钢铁冶炼', 'stock_count': 18}, {'id': 402, 'name': '钢铁制品', 'stock_count': 14} ] }, { 'id': 5, 'name': '有色金属', 'code': '801050', 'description': '有色金属冶炼、有色金属制品', 'stock_count': 67, 'avg_change': 1.8, 'total_market_cap': 900000000000, 'sub_industries': [ {'id': 501, 'name': '有色金属冶炼', 'stock_count': 35}, {'id': 502, 'name': '有色金属制品', 'stock_count': 32} ] }, { 'id': 6, 'name': '建筑材料', 'code': '801060', 'description': '水泥、玻璃、陶瓷、其他建材', 'stock_count': 89, 'avg_change': 1.1, 'total_market_cap': 700000000000, 'sub_industries': [ {'id': 601, 'name': '水泥', 'stock_count': 25}, {'id': 602, 'name': '玻璃', 'stock_count': 18}, {'id': 603, 'name': '陶瓷', 'stock_count': 12}, {'id': 604, 'name': '其他建材', 'stock_count': 34} ] }, { 'id': 7, 'name': '建筑装饰', 'code': '801070', 'description': '房屋建设、装修装饰、园林工程', 'stock_count': 45, 'avg_change': 0.9, 'total_market_cap': 400000000000, 'sub_industries': [ {'id': 701, 'name': '房屋建设', 'stock_count': 15}, {'id': 702, 'name': '装修装饰', 'stock_count': 20}, {'id': 703, 'name': '园林工程', 'stock_count': 10} ] }, { 'id': 8, 'name': '电气设备', 'code': '801080', 'description': '电机、电气自动化设备、电源设备', 'stock_count': 134, 'avg_change': 2.1, 'total_market_cap': 1500000000000, 'sub_industries': [ {'id': 801, 'name': '电机', 'stock_count': 25}, {'id': 802, 'name': '电气自动化设备', 'stock_count': 45}, {'id': 803, 'name': '电源设备', 'stock_count': 64} ] }, { 'id': 9, 'name': '国防军工', 'code': '801090', 'description': '航天装备、航空装备、地面兵装', 'stock_count': 28, 'avg_change': 1.6, 'total_market_cap': 300000000000, 'sub_industries': [ {'id': 901, 'name': '航天装备', 'stock_count': 8}, {'id': 902, 'name': '航空装备', 'stock_count': 12}, {'id': 903, 'name': '地面兵装', 'stock_count': 8} ] }, { 'id': 10, 'name': '汽车', 'code': '801100', 'description': '汽车整车、汽车零部件', 'stock_count': 78, 'avg_change': 1.3, 'total_market_cap': 1100000000000, 'sub_industries': [ {'id': 1001, 'name': '汽车整车', 'stock_count': 25}, {'id': 1002, 'name': '汽车零部件', 'stock_count': 53} ] }, { 'id': 11, 'name': '家用电器', 'code': '801110', 'description': '白色家电、小家电、家电零部件', 'stock_count': 56, 'avg_change': 1.0, 'total_market_cap': 800000000000, 'sub_industries': [ {'id': 1101, 'name': '白色家电', 'stock_count': 20}, {'id': 1102, 'name': '小家电', 'stock_count': 18}, {'id': 1103, 'name': '家电零部件', 'stock_count': 18} ] }, { 'id': 12, 'name': '纺织服装', 'code': '801120', 'description': '纺织制造、服装家纺', 'stock_count': 67, 'avg_change': 0.7, 'total_market_cap': 500000000000, 'sub_industries': [ {'id': 1201, 'name': '纺织制造', 'stock_count': 35}, {'id': 1202, 'name': '服装家纺', 'stock_count': 32} ] }, { 'id': 13, 'name': '轻工制造', 'code': '801130', 'description': '造纸、包装印刷、家用轻工', 'stock_count': 89, 'avg_change': 0.9, 'total_market_cap': 600000000000, 'sub_industries': [ {'id': 1301, 'name': '造纸', 'stock_count': 25}, {'id': 1302, 'name': '包装印刷', 'stock_count': 30}, {'id': 1303, 'name': '家用轻工', 'stock_count': 34} ] }, { 'id': 14, 'name': '医药生物', 'code': '801140', 'description': '化学制药、中药、生物制品、医疗器械', 'stock_count': 234, 'avg_change': 1.9, 'total_market_cap': 2500000000000, 'sub_industries': [ {'id': 1401, 'name': '化学制药', 'stock_count': 78}, {'id': 1402, 'name': '中药', 'stock_count': 45}, {'id': 1403, 'name': '生物制品', 'stock_count': 56}, {'id': 1404, 'name': '医疗器械', 'stock_count': 55} ] }, { 'id': 15, 'name': '公用事业', 'code': '801150', 'description': '电力、燃气、水务', 'stock_count': 78, 'avg_change': 0.5, 'total_market_cap': 900000000000, 'sub_industries': [ {'id': 1501, 'name': '电力', 'stock_count': 45}, {'id': 1502, 'name': '燃气', 'stock_count': 18}, {'id': 1503, 'name': '水务', 'stock_count': 15} ] }, { 'id': 16, 'name': '交通运输', 'code': '801160', 'description': '港口、公路、铁路、航空', 'stock_count': 67, 'avg_change': 0.8, 'total_market_cap': 800000000000, 'sub_industries': [ {'id': 1601, 'name': '港口', 'stock_count': 15}, {'id': 1602, 'name': '公路', 'stock_count': 20}, {'id': 1603, 'name': '铁路', 'stock_count': 12}, {'id': 1604, 'name': '航空', 'stock_count': 20} ] }, { 'id': 17, 'name': '房地产', 'code': '801170', 'description': '房地产开发、房地产服务', 'stock_count': 89, 'avg_change': 0.6, 'total_market_cap': 1200000000000, 'sub_industries': [ {'id': 1701, 'name': '房地产开发', 'stock_count': 65}, {'id': 1702, 'name': '房地产服务', 'stock_count': 24} ] }, { 'id': 18, 'name': '商业贸易', 'code': '801180', 'description': '贸易、零售', 'stock_count': 78, 'avg_change': 0.7, 'total_market_cap': 600000000000, 'sub_industries': [ {'id': 1801, 'name': '贸易', 'stock_count': 35}, {'id': 1802, 'name': '零售', 'stock_count': 43} ] }, { 'id': 19, 'name': '休闲服务', 'code': '801190', 'description': '景点、酒店、旅游综合', 'stock_count': 34, 'avg_change': 1.2, 'total_market_cap': 300000000000, 'sub_industries': [ {'id': 1901, 'name': '景点', 'stock_count': 12}, {'id': 1902, 'name': '酒店', 'stock_count': 15}, {'id': 1903, 'name': '旅游综合', 'stock_count': 7} ] }, { 'id': 20, 'name': '银行', 'code': '801200', 'description': '银行', 'stock_count': 28, 'avg_change': 0.4, 'total_market_cap': 8000000000000, 'sub_industries': [ {'id': 2001, 'name': '银行', 'stock_count': 28} ] }, { 'id': 21, 'name': '非银金融', 'code': '801210', 'description': '保险、证券、多元金融', 'stock_count': 45, 'avg_change': 0.8, 'total_market_cap': 2000000000000, 'sub_industries': [ {'id': 2101, 'name': '保险', 'stock_count': 8}, {'id': 2102, 'name': '证券', 'stock_count': 25}, {'id': 2103, 'name': '多元金融', 'stock_count': 12} ] }, { 'id': 22, 'name': '综合', 'code': '801220', 'description': '综合', 'stock_count': 23, 'avg_change': 0.6, 'total_market_cap': 200000000000, 'sub_industries': [ {'id': 2201, 'name': '综合', 'stock_count': 23} ] }, { 'id': 23, 'name': '计算机', 'code': '801230', 'description': '计算机设备、计算机应用', 'stock_count': 156, 'avg_change': 2.3, 'total_market_cap': 1800000000000, 'sub_industries': [ {'id': 2301, 'name': '计算机设备', 'stock_count': 45}, {'id': 2302, 'name': '计算机应用', 'stock_count': 111} ] }, { 'id': 24, 'name': '传媒', 'code': '801240', 'description': '文化传媒、营销传播', 'stock_count': 78, 'avg_change': 1.4, 'total_market_cap': 700000000000, 'sub_industries': [ {'id': 2401, 'name': '文化传媒', 'stock_count': 45}, {'id': 2402, 'name': '营销传播', 'stock_count': 33} ] }, { 'id': 25, 'name': '通信', 'code': '801250', 'description': '通信设备、通信运营', 'stock_count': 45, 'avg_change': 1.7, 'total_market_cap': 600000000000, 'sub_industries': [ {'id': 2501, 'name': '通信设备', 'stock_count': 30}, {'id': 2502, 'name': '通信运营', 'stock_count': 15} ] }, { 'id': 26, 'name': '电子', 'code': '801260', 'description': '半导体、电子制造、光学光电子', 'stock_count': 178, 'avg_change': 2.0, 'total_market_cap': 2000000000000, 'sub_industries': [ {'id': 2601, 'name': '半导体', 'stock_count': 45}, {'id': 2602, 'name': '电子制造', 'stock_count': 78}, {'id': 2603, 'name': '光学光电子', 'stock_count': 55} ] }, { 'id': 27, 'name': '机械设备', 'code': '801270', 'description': '通用机械、专用设备、仪器仪表', 'stock_count': 234, 'avg_change': 1.1, 'total_market_cap': 1500000000000, 'sub_industries': [ {'id': 2701, 'name': '通用机械', 'stock_count': 89}, {'id': 2702, 'name': '专用设备', 'stock_count': 98}, {'id': 2703, 'name': '仪器仪表', 'stock_count': 47} ] }, { 'id': 28, 'name': '食品饮料', 'code': '801280', 'description': '食品加工、饮料制造', 'stock_count': 67, 'avg_change': 1.3, 'total_market_cap': 1000000000000, 'sub_industries': [ {'id': 2801, 'name': '食品加工', 'stock_count': 35}, {'id': 2802, 'name': '饮料制造', 'stock_count': 32} ] } ] return jsonify({ 'success': True, 'data': levels }) except Exception as e: print(f"Error getting industry levels: {e}") return jsonify({'success': False, 'error': str(e)}), 500 @bp.route('/info', methods=['GET']) def get_industry_info(): """获取行业信息""" try: industry_id = request.args.get('industry_id') if not industry_id: return jsonify({'success': False, 'error': '请提供行业ID'}), 400 # 模拟行业信息 industry_info = { 'id': industry_id, 'name': f'行业{industry_id}', 'code': f'801{industry_id.zfill(3)}', 'description': f'这是行业{industry_id}的详细描述', 'stock_count': 50, 'avg_change': 1.5, 'total_market_cap': 800000000000, 'pe_ratio': 15.6, 'pb_ratio': 2.3, 'roe': 8.5, 'top_stocks': [ {'code': '000001', 'name': '龙头股A', 'weight': 0.15}, {'code': '000002', 'name': '龙头股B', 'weight': 0.12}, {'code': '000003', 'name': '龙头股C', 'weight': 0.10} ], 'sub_industries': [ {'id': 1, 'name': '子行业A', 'stock_count': 20}, {'id': 2, 'name': '子行业B', 'stock_count': 18}, {'id': 3, 'name': '子行业C', 'stock_count': 12} ], 'performance': { 'daily': 1.5, 'weekly': 3.2, 'monthly': 8.5, 'quarterly': 12.3, 'yearly': 25.6 }, 'trend': { 'direction': 'up', 'strength': 'medium', 'duration': '3 months' } } return jsonify({ 'success': True, 'data': industry_info }) except Exception as e: print(f"Error getting industry info: {e}") return jsonify({'success': False, 'error': str(e)}), 500