diff --git a/app/web/main.py b/app/web/main.py index a8ab670..788efe9 100644 --- a/app/web/main.py +++ b/app/web/main.py @@ -388,6 +388,24 @@ def api_positions(): tech_service.attach(v["positions"]) except Exception as e: # noqa: BLE001 logger.warning("[持仓] 技术面立场挂不上: %s", e) + # 综合分析三票 (2026-09-15): 每行挂 dims = {fund, tech, timing, fund_fact, tech_phase, nightly}, + # 供持仓表「综合分析」列三枚维度标签用。与扫描同一套装配 (consensus_service.decorate_positions: + # 基本面从逻辑状态映射的买方评析算, 技术面用早上映射, 择时用昨夜定性); 只是显示, 取不到不塌。 + try: + from app.services import consensus_service + _lmap = logic_state_service.state_map() or {} + _crs = {code: (st or {}).get("company_review") for code, st in _lmap.items()} + consensus_service.decorate_positions(v["positions"], company_reviews=_crs) + for r in v["positions"]: + b = r.pop("consensus_blocks", None) or {} + fund, tech, tm = b.get("fund") or {}, b.get("tech") or {}, b.get("timing") or {} + # 技术面优先用 tech_service.attach 挂的那份 (同一映射, 已带相位与理由) + t = r.get("tech") or tech + r["dims"] = {"fund": fund.get("stance"), "fund_fact": fund.get("fact") or fund.get("no_read_why"), + "tech": t.get("stance"), "tech_phase": t.get("phase"), + "timing": tm.get("stance"), "nightly": tm.get("nightly")} + except Exception as e: # noqa: BLE001 + logger.warning("[持仓] 综合分析三票挂不上: %s", e) return {"ok": True, **v, "stock_params": sp} return ok(_view) diff --git a/app/web/static/index.html b/app/web/static/index.html index a4acf98..8f592d0 100644 --- a/app/web/static/index.html +++ b/app/web/static/index.html @@ -344,8 +344,9 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;} border-bottom:1px dashed rgba(128,128,128,.16);font-size:12.5px;} .sigrow2:last-child{border-bottom:none;} .sigrow2 .t{width:36px;flex:none;font-size:11px;color:var(--muted);} -.sigrow2 .nm{font-weight:620;white-space:nowrap;} -.sigrow2 .cat{color:var(--muted);font-size:11.5px;white-space:nowrap;} +.sigrow2 .nm{font-weight:620;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;} +.sigrow2 .cat{color:var(--muted);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:34%;} +.sigrow2 .dim,.sigrow2 .disp{flex:none;white-space:nowrap;} .sigrow2 .sp{flex:1;} .sigrow2.old{opacity:.5;} .sigrow2.clk{cursor:pointer;border-radius:4px;} @@ -449,6 +450,7 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;} .dim.down{background:var(--down-weak);color:var(--down);} .dim.neutral{background:rgba(138,136,130,.14);color:var(--ink-2);} .dim.na{background:transparent;color:var(--muted);border:1px dashed var(--hair);padding:0 6px;} +.dims{display:flex;gap:4px;flex-wrap:wrap;align-items:center;} .prop-sheet{position:fixed;left:0;right:0;bottom:0;z-index:3000;max-height:86vh;overflow:auto; background:var(--surface);border-radius:16px 16px 0 0;box-shadow:0 -12px 40px rgba(17,17,16,.22);} .prop-metric{display:flex;flex-direction:column;gap:7px;margin:8px 0;} @@ -976,15 +978,13 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;}