diff --git a/app.py b/app.py
index a7818e23..43eda8a5 100755
--- a/app.py
+++ b/app.py
@@ -11682,9 +11682,9 @@ def get_value_chain_analysis(company_code):
@app.route('/api/company/value-chain/related-companies', methods=['GET'])
def get_related_companies_by_node():
"""
- 根据产业链节点名称查询相关公司
+ 根据产业链节点名称查询相关公司(结合nodes和flows表)
参数: node_name - 节点名称(如 "中芯国际"、"EDA/IP"等)
- 返回: 包含该节点的所有公司列表(去重)
+ 返回: 包含该节点的所有公司列表,附带节点层级、类型、关系描述等信息
"""
try:
node_name = request.args.get('node_name')
@@ -11695,29 +11695,88 @@ def get_related_companies_by_node():
'error': '缺少必需参数 node_name'
}), 400
- # 查询包含该节点的所有公司
+ # 查询包含该节点的所有公司及其节点信息
query = text("""
SELECT DISTINCT
n.company_code as stock_code,
s.SECNAME as stock_name,
- s.ORGNAME as company_name
+ s.ORGNAME as company_name,
+ n.node_level,
+ n.node_type,
+ n.node_description,
+ n.importance_score,
+ n.market_share,
+ n.dependency_degree
FROM company_value_chain_nodes n
LEFT JOIN ea_stocklist s ON n.company_code = s.SECCODE
WHERE n.node_name = :node_name
- ORDER BY n.company_code
+ ORDER BY n.importance_score DESC, n.company_code
""")
with engine.connect() as conn:
- result = conn.execute(query, {'node_name': node_name}).fetchall()
+ nodes_result = conn.execute(query, {'node_name': node_name}).fetchall()
# 构建返回数据
companies = []
- for row in result:
- companies.append({
+ for row in nodes_result:
+ company_data = {
'stock_code': row.stock_code,
'stock_name': row.stock_name or row.stock_code,
- 'company_name': row.company_name
- })
+ 'company_name': row.company_name,
+ 'node_info': {
+ 'node_level': row.node_level,
+ 'node_type': row.node_type,
+ 'node_description': row.node_description,
+ 'importance_score': row.importance_score,
+ 'market_share': format_decimal(row.market_share),
+ 'dependency_degree': format_decimal(row.dependency_degree)
+ },
+ 'relationships': []
+ }
+
+ # 查询该节点在该公司产业链中的流向关系
+ flows_query = text("""
+ SELECT
+ source_node,
+ source_type,
+ source_level,
+ target_node,
+ target_type,
+ target_level,
+ flow_type,
+ relationship_desc,
+ flow_value,
+ flow_ratio
+ FROM company_value_chain_flows
+ WHERE company_code = :company_code
+ AND (source_node = :node_name OR target_node = :node_name)
+ ORDER BY flow_ratio DESC
+ LIMIT 5
+ """)
+
+ with engine.connect() as conn:
+ flows_result = conn.execute(flows_query, {
+ 'company_code': row.stock_code,
+ 'node_name': node_name
+ }).fetchall()
+
+ # 添加流向关系信息
+ for flow in flows_result:
+ # 判断节点在流向中的角色
+ is_source = (flow.source_node == node_name)
+
+ relationship = {
+ 'role': 'source' if is_source else 'target',
+ 'connected_node': flow.target_node if is_source else flow.source_node,
+ 'connected_type': flow.target_type if is_source else flow.source_type,
+ 'connected_level': flow.target_level if is_source else flow.source_level,
+ 'flow_type': flow.flow_type,
+ 'relationship_desc': flow.relationship_desc,
+ 'flow_ratio': format_decimal(flow.flow_ratio)
+ }
+ company_data['relationships'].append(relationship)
+
+ companies.append(company_data)
return jsonify({
'success': True,
diff --git a/src/views/Company/CompanyOverview.js b/src/views/Company/CompanyOverview.js
index e4ab6372..0f069ef6 100644
--- a/src/views/Company/CompanyOverview.js
+++ b/src/views/Company/CompanyOverview.js
@@ -468,34 +468,126 @@ const ValueChainNodeCard = ({ node, isCompany = false, level = 0 }) => {