diff --git a/app/web/static/index.html b/app/web/static/index.html index 67c5a3d..0cd544b 100644 --- a/app/web/static/index.html +++ b/app/web/static/index.html @@ -322,18 +322,21 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;} @container (max-width:1100px){ .tmain .metrics{grid-template-columns:repeat(4,minmax(0,1fr));} } @container (max-width:560px){ .tmain .metrics{grid-template-columns:repeat(2,minmax(0,1fr));} } .tmain .panel{padding:14px 16px;margin-bottom:13px;} -/* 持仓表: 操作列用 Element Plus 的 fixed="right" 钉住, 表格自己横向滚动 */ -.postbl .el-table__fixed-right{box-shadow:-9px 0 11px -11px rgba(17,17,16,.4);} -.act-cell{display:flex;gap:5px;align-items:center;flex-wrap:nowrap;} -/* 钉住的操作列要不透明, 否则下面那列的文字会透上来 (表格背景被设成了 transparent) */ -.postbl .el-table__fixed-right{background:var(--surface);} +/* 持仓表 (2026-09-15 重排): 操作列折叠成一枚「⋯」(58 像素), 仍用 fixed="right" 钉住 —— 表格放得下时它就在原位, + 中栏比表格窄时其余列横向滚动、它始终可点; 原来三枚按钮钉住 172 像素, 会盖住「状态 · 下一步」。 + 状态芯片一行、「下一步」短语一行放下, 具体说明进悬停。 */ .postbl .el-scrollbar__wrap{overflow-x:auto;} +/* 钉住的列要不透明, 否则滚动时下面那列的文字会透上来 (表格背景被设成了 transparent) */ +.postbl .el-table__fixed-right{background:var(--surface);box-shadow:-9px 0 11px -11px rgba(17,17,16,.4);} .postbl .el-table__fixed-right .el-table__cell, .postbl td.el-table-fixed-column--right{background:var(--surface)!important;} .postbl .el-table__fixed-right th.el-table__cell, .postbl th.el-table-fixed-column--right{background:var(--surface-2)!important;} .postbl .el-table__body tr:hover>td.el-table-fixed-column--right, .postbl .el-table__fixed-right .el-table__row:hover>.el-table__cell{background:var(--surface-2)!important;} +.postbl .chips{display:flex;flex-wrap:wrap;gap:4px;align-items:center;} +.postbl .nx{margin-top:3px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;} +.postbl .morebtn{padding:4px 9px;font-weight:700;letter-spacing:1px;} /* ── 左栏 信号流 ── */ .railtabs{display:flex;gap:3px;margin-bottom:8px;background:var(--surface-2);border-radius:8px;padding:2px;} @@ -917,7 +920,7 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;}
· {{ a }}
- +

持仓 · {{ heldPositions.length }} 只

安全垫? @@ -1010,31 +1013,37 @@ body.dock-r:not(.r-fold) .side-r .strip{display:none;} title="速览只留了每类最新的若干条,这里的「没有」可能是假的。点一下按代码回扫今天全部。">今天没有 - + + - + + @@ -3263,12 +3272,48 @@ createApp({ const l = (p.hard_numbers || {}).logic; return Array.isArray(l) && l.length > 1 ? (l.length - 1) : 0; } - function nextStep(r) { - if (r.frozen_reason && r.frozen_reason !== 'NONE') return '这只票当前只卖不买。'; - if (r.cushion_state === 'SOLID') return '浮盈够厚,条件符合即自动加仓。'; - if ((r.cushion_pct || 0) < 0) return '仍在浮亏。跌到补仓线考虑补仓;更深一档的补仓按系统自决处理(自决关时需人工确认)。'; - return '持有观察。'; + // 持仓行的「下一步」(2026-09-15 重写): 单元格只放一句短语 (nextStep), 具体说明进悬停 (nextStepWhy)。 + // 挂着交易方案的票先说方案: 动作引擎对方案票只评目标价, 补足/加仓/补仓/保垫减仓与转空离场都由方案层接管 + // (action_engine.scan 「策略票只看目标价」), 常规纪律那几句对它不成立。方案按票取: 运行中优先于已暂停。 + const stratByCode = computed(() => { + const m = {}; + for (const s of (strategies.value || [])) { + if (_isArch(s) || !_STRAT_ACTIVE.includes(s.status)) continue; + if (!m[s.ts_code] || (s.status === 'ACTIVE' && m[s.ts_code].status !== 'ACTIVE')) m[s.ts_code] = s; + } + return m; + }); + const stratOf = code => stratByCode.value[code] || null; + const _STRAT_HOW = { GRID: '跌到下一档自动买入,涨回上一档自动卖出', + T0: '盘中按触发条件先买后卖或先卖后买回,当日了结', + TRAIL: '价格从高点回落到止盈线即自动卖出' }; + function nextStepOf(r) { + const tail = r.user_target_price != null ? '到目标价 ' + r.user_target_price + ' 系统清仓。' : ''; + if (r.frozen_reason && r.frozen_reason !== 'NONE') { + return { text: '不增持,减持照常', + why: tx('frozen', r.frozen_reason) + '。回踩补足、盈利加仓、补仓都不做;减仓、清仓、到目标价清仓照常。恢复买入在「操作」菜单里。' }; + } + const s = stratOf(r.ts_code); + if (s) { + const kind = tx('stype', s.type), st = stratStateText(s); + if (s.status === 'PAUSED') return { text: kind + '方案已暂停', + why: kind + '方案已暂停,方案层不买不卖;在右栏「交易方案」里恢复或撤下。' + (st ? st + '。' : '') + tail }; + if (s.buy_paused) return { text: kind + '只卖不买', + why: '决策系统提示' + (s.buy_paused.reason || '资金异动') + ',方案的买入腿已停;卖出与把当天做T买的那部分卖回去不受影响。' + st + '。' + tail }; + return { text: kind + '运行中 · ' + st.split(' · ')[0], + why: kind + '方案运行中:' + (_STRAT_HOW[s.type] || '') + ';' + st + '。方案票不走常规的补足、加仓、补仓与保垫减仓,SAR 止损由方案层管。' + + (tail || '设了目标价才会到价清仓。') }; + } + const d = dimsOf(r); + if (d.tech_phase === '转空') return { text: '离场纪律', why: '技术面刚转空,按纪律减持或清仓,自动还是人工由转空离场档位决定。' + tail }; + if (d.tech === '看空') return { text: '增持受限', why: '技术面偏空,暂停回踩补足与盈利加仓,减持照常。' + tail }; + if (d.fund === '看空') return { text: '补仓受限', why: '基本面偏弱,暂停补仓;其余纪律照常。' + tail }; + if (r.cushion_state === 'SOLID') return { text: '条件符合即加仓', why: '浮盈够厚,回踩补足或盈利加仓的条件符合即自动加仓,受增持门约束。' + tail }; + if ((r.cushion_pct || 0) < 0) return { text: '浮亏,等补仓线', why: '仍在浮亏。跌到补仓线考虑补仓;更深一档的补仓按系统自决处理(自决关时需人工确认)。' + tail }; + return { text: '持有观察', why: '浮盈不厚,暂不加仓;技术面转空时按离场纪律处理。' + tail }; } + function nextStep(r) { return nextStepOf(r).text; } + function nextStepWhy(r) { return nextStepOf(r).why; } async function promptNum(msg, title) { try { @@ -3339,7 +3384,9 @@ createApp({ } function actBlacklist(row) { quickCmd('BLACKLIST_ADD', { ts_code: row.ts_code }, '把 ' + nm(row.ts_code) + ' 加入黑名单(永不买入)?'); } function rowMore(c, row) { - if (c === 'stop') actStop(row); + if (c === 'reduce') actReduceStock(row); + else if (c === 'exit') actExitStock(row); + else if (c === 'stop') actStop(row); else if (c === 'target') actTargetPrice(row); else if (c === 'freeze') actFreeze(row); else if (c === 'black') actBlacklist(row); @@ -4533,7 +4580,7 @@ createApp({ chgRaw, chgSt, chgLoading, chgTab, chg, chgHeld, chgLog, chgRevised, chgWatch, loadChanges, mode, tx, nm, fullName, nameMap, attention, heldPositions, traderParams, - propWhy, propReasons, nextStep, scrollTo, actExitStock, actReduceStock, rowMore, + propWhy, propReasons, nextStep, nextStepWhy, stratOf, scrollTo, actExitStock, actReduceStock, rowMore, // 2026-09-10 修白屏。下面这十一个显示函数在 setup 里定义了、模板里也在用, // 但从 2026-09-04 那批文案改造起就一直没写进这份清单, 模板拿到的是 undefined。 // 平时提议队列为空、那几行 v-if 不成立所以从不调用, 09-10 早上队列里出现