diff --git a/agents/stock/workspace/scripts/behive_web.py b/agents/stock/workspace/scripts/behive_web.py index 2e9a44e..7113f2f 100644 --- a/agents/stock/workspace/scripts/behive_web.py +++ b/agents/stock/workspace/scripts/behive_web.py @@ -4439,6 +4439,10 @@ dl.pending-detail .pending-line-meta { margin-top: 2px; } .info-tabbtn:hover { color: #d6d8dd; } .info-tabbtn.active { color: #f0f0f0; border-bottom-color: #ff4d5e; } .info-tabpanel[hidden] { display: none; } +/* 탭 상단 내용 요약 박스 */ +.info-summary { background: #11161f; border: 1px solid #232a36; border-left: 3px solid #4a8cf0; border-radius: 8px; padding: 9px 11px; margin: 0 0 12px; } +.info-summary-t { font-size: 11px; color: #7a8493; font-weight: 600; margin-bottom: 4px; } +.info-summary-b { font-size: 13px; color: #cfd5df; line-height: 1.75; } .info-q { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0; margin-left: 4px; border-radius: 50%; border: 1px solid rgba(125,211,168,0.4); background: rgba(125,211,168,0.08); color: #7dd3a8; font-size: 10px; font-weight: 700; line-height: 1; cursor: pointer; font-family: inherit; vertical-align: middle; } .info-q:hover { background: rgba(125,211,168,0.2); border-color: #7dd3a8; } .info-q:active { transform: translateY(1px); } @@ -7884,8 +7888,29 @@ def render_html() -> str: 'if(j.reports&&j.reports.length){var r=j.reports[0];var ar="";if(r.target_action&&r.target_action.indexOf("상향")>=0)ar=\' \';else if(r.target_action&&r.target_action.indexOf("하향")>=0)ar=\' \';h+=\'
최신 리포트
\'+escHtml(r.date||"")+\' \'+escHtml(r.broker||"")+\' \'+(r.target?\'목표 \'+escHtml(r.target)+ar+\'\':"")+\'
\'+escHtml(r.title||"")+\'
\';}' 'return h;' '}' - 'var companyInner=titled("가치지표",secGrid("가치지표"))+titled("기본정보",secGrid("기본정보"));' - 'var growthInner=secGrid("성장성·컨센서스");' + # 탭 상단 내용 요약 박스 — 핵심 수치를 한 묶음으로 + 간단 해석(규칙 기반, 데이터 그대로). + 'function infoSummaryBox(inner){return inner?(\'
📝 요약
\'+inner+\'
\'):"";}' + 'function companySummary(j){' + 'var L=[],per=Number(j.per),pbr=Number(j.pbr),roe=Number(j.roe),val=[];' + 'if(j.per!=null&&j.per!==""&&!isNaN(per))val.push("PER "+per.toFixed(2)+"배");' + 'if(j.pbr!=null&&j.pbr!==""&&!isNaN(pbr))val.push("PBR "+pbr.toFixed(2)+"배");' + 'if(val.length)L.push("밸류에이션 "+val.join(" · "));' + 'if(j.roe!=null&&j.roe!==""&&!isNaN(roe)){var tag=roe<0?"적자":(roe>=15?"우수":(roe>=8?"양호":"다소 낮음"));L.push("수익성 ROE "+roe.toFixed(1)+"% ("+tag+")");}' + 'return infoSummaryBox(L.join("
"));' + '}' + 'function growthSummary(j){' + 'var gr=(j.fundamentals&&j.fundamentals.growth)||{},fc=(j.fundamentals&&j.fundamentals.consensus)||{},cn=j.consensus||{},L=[],g=[];' + 'if(gr.sales_yoy!=null)g.push("매출 "+growthDisp(gr.sales_yoy));' + 'if(gr.oper_profit_yoy!=null)g.push("영익 "+growthDisp(gr.oper_profit_yoy));' + 'if(gr.eps_yoy!=null)g.push("EPS "+growthDisp(gr.eps_yoy));' + 'if(g.length)L.push("성장(YoY) "+g.join(" · "));' + 'if(fc.target_price!=null){var p=Number(j.price),tp=Number(fc.target_price),up="";if(p&&tp&&!isNaN(p)&&!isNaN(tp))up=" (상승여력 "+growthDisp((tp/p-1)*100)+")";L.push("목표주가 "+fmtInt(fc.target_price)+"원"+up+(fc.opinion_label?" · "+escHtml(fc.opinion_label):""));}' + 'if(cn.target_change_pct!=null)L.push("목표가 리비전(3M) "+growthDisp(cn.target_change_pct));' + 'if(cn.surprise_op!=null)L.push("영익 서프라이즈 "+growthDisp(cn.surprise_op));' + 'return infoSummaryBox(L.join("
"));' + '}' + 'var companyInner=companySummary(j)+titled("가치지표",secGrid("가치지표"))+titled("기본정보",secGrid("기본정보"));' + 'var growthInner=growthSummary(j)+secGrid("성장성·컨센서스");' 'var repInner=infoReportsHtml(j);' 'var TB=[["summary","요약",sumPanel()],["company","기업정보·가치",companyInner],["growth","성장성·컨센서스",growthInner],["reports","투자리포트",repInner]];' 'var bar=\'
\';var pans="";'