Commit bf9f86d0 by luoqi

fix(分配): 本地改单后撤掉已经不成立的引导节点(浏览器实测抓到)

现象:点了「各自归专属客服」,72 人的待分配已经清零、汇总行也更新成
「拟分 103 人」,而节点区还挂着「72 人的专属客服这轮已排满」+ 四个按钮 ——
再点一次是空操作,主管只会觉得"我明明处理过了"。

根因:signals 是**服务端随提案下发的快照**,本地 edit 只改了前端的生效条目,
没有任何东西去更新它。违了引导节点设计规则④「每次重算,不做增量」。

修法:只撤掉**主语已经消失**的那些,判据全部来自卡片本地看得见的事实:
  · pending        —— 待分配被处置光了,这条没有主语了
  · expiry_default —— 主管改过时效,"用的是默认值"就不成立了
 **不在前端重算判定** —— 判定逻辑复制到两边必然漂(T6a 同源)。
其余(候选不足 / 工作量 / 画像亮点)本地改单不影响、或需重跑才知道 → 原样留着。

️ 这个 bug 单测抓不到:逻辑各自都对,错在"服务端快照 + 本地可变状态"的接缝上。
只有真的点一下才看得见。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent 77e84aaf
......@@ -991,6 +991,23 @@ export function AssignmentConfirmSheet({
onIntent?.(intent, args);
};
/**
* 主语还在的引导节点。
* ⚠️ 判据只用**卡片本地就能看见**的事实,⛔ 不重算服务端的判定:
* · `pending` —— 待分配被处置光了,这条就没有主语了
* · `expiry_default` —— 主管改过时效,"用的是默认值"这句话就不成立了
* 其余(候选不足 / 工作量 / 画像亮点)本地改单不影响,或需重跑才知道 → 原样留着。
*/
const liveSignals = useMemo(
() =>
(sheet.signals ?? []).filter((s) => {
if (s.key === 'pending') return pendingList.length > 0;
if (s.key === 'expiry_default') return expiresInDays === sheet.expiresInDays;
return true;
}),
[sheet.signals, sheet.expiresInDays, pendingList.length, expiresInDays],
);
const rootRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let el = rootRef.current?.parentElement ?? null;
......@@ -1101,9 +1118,16 @@ export function AssignmentConfirmSheet({
主管的视线从汇总行往下走,"还有什么要我定的"必须在这一跳里被看到;
埋到底部就等于没有(那正是「待分配」当初被漏掉的原因)。
⚠️ 判定在服务端(signals 随提案下发),这里只呈现 + 把 intent 抛给 handleIntent。
🔴 **本地改单之后要撤掉已经不成立的节点**(2026-08-12 浏览器实测抓到):
点了「各自归专属客服」,72 人的待分配已经清零、汇总行也更新了,
而节点区还挂着「72 人的专属客服这轮已排满」+ 四个按钮 —— 再点一次是空操作,
主管只会觉得"我明明处理过了"。
⚠️ 这里**只撤掉主语已经消失的那些**,⛔ 不在前端重算判定 ——
判定逻辑复制到两边必然漂(T6a 同源)。要真正重算得让服务端重出一版。
*/}
<ConfirmSheetSignals
signals={sheet.signals ?? []}
signals={liveSignals}
readOnly={readOnly}
busyIntent={busyIntent}
onIntent={handleIntent}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment