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="速览只留了每类最新的若干条,这里的「没有」可能是假的。点一下按代码回扫今天全部。">今天没有
-
+
+
- {{ tx('posStatus', s.row.status) }}
- {{ tx('frozen', s.row.frozen_reason) }}
- {{ nextStep(s.row) }}
+
+ {{ tx('posStatus', s.row.status) }}
+ {{ tx('stype', stratOf(s.row.ts_code).type) }}
+ 只卖不买
+
+ {{ nextStep(s.row) }}
-
+
+
-
- 减仓
- 清仓
- rowMore(c,s.row)">
- ⋯
-
-
- 设止损价
- 设目标价
- {{ (s.row.frozen_reason && s.row.frozen_reason!=='NONE') ? '恢复买入' : '改成只卖不买' }}
- 加入黑名单
- 挂交易方案(做T / 网格 / 跟踪止盈)
-
-
-
-
+ rowMore(c,s.row)">
+ ⋯
+
+
+ 减仓
+ 清仓
+ 设止损价
+ 设目标价
+ {{ (s.row.frozen_reason && s.row.frozen_reason!=='NONE') ? '恢复买入' : '改成只卖不买' }}
+ 加入黑名单
+ 挂交易方案(做T / 网格 / 跟踪止盈)
+
+
+
@@ -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 早上队列里出现