Archived
fix(web): 录入卡在等人时,工作区摆占位页,不摆件
建档那一步(「客户 123 不在客户档案里,请核对建档」)要人做的事全在对话区那张录入卡上, 而工作区里躺着的是**上一拍**推的 HTML 件 —— 摆着只会让人以为要在那份工单上办点什么。 `pendingCardsOf`(纯函数,5 测)认出未确认的录入卡 → `ViewRegion` 在 running 之后、viewHtml 之前 插一支占位 `EmptyState`(点名那张表的人读名,指向对话区)。 决策卡**不走**这一支 —— 人要决定的对象常常就是件上那份稿,件得留着给他看。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0167qWjeyBwvfdGovd7FWbCu
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 工作区看对话区的脸色 —— 录入卡在等人时摆占位页,不摆件(2026-08-28 用户定)。
|
||||
*/
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { dataEntryCardSchema, decisionCardSchema } from '@contracts';
|
||||
import type { TaskDetail } from '@contracts';
|
||||
import { pendingCardsOf } from '../internal/pending-cards.ts';
|
||||
|
||||
const AT = '2026-08-28T00:55:30.054Z';
|
||||
|
||||
function entry(id: string, extra: Record<string, unknown> = {}) {
|
||||
return dataEntryCardSchema.parse({
|
||||
k: 'entry',
|
||||
id,
|
||||
at: AT,
|
||||
ask: '客户 123 不在客户档案里,请核对建档信息后确认',
|
||||
ledger: 'customer.profile',
|
||||
ledgerLabel: '客户档案',
|
||||
key: { customer_code: '123' },
|
||||
fields: [],
|
||||
...extra,
|
||||
});
|
||||
}
|
||||
|
||||
function decision(id: string, extra: Record<string, unknown> = {}) {
|
||||
return decisionCardSchema.parse({
|
||||
k: 'decision',
|
||||
id,
|
||||
at: AT,
|
||||
ask: '经营计划是否通过?',
|
||||
basis: [{ k: '依据', v: '计划表 4 行' }],
|
||||
options: [
|
||||
{ value: 'pass', label: '通过' },
|
||||
{ value: 'reject', label: '驳回' },
|
||||
],
|
||||
...extra,
|
||||
});
|
||||
}
|
||||
|
||||
const chat = (...items: TaskDetail['chat']): TaskDetail['chat'] => items;
|
||||
|
||||
describe('pendingCardsOf', () => {
|
||||
it('未确认的录入卡在场 → entry,并带上那张表的人读名', () => {
|
||||
expect(pendingCardsOf(chat(entry('c-1')))).toEqual({ decision: false, entry: true, entryLedger: '客户档案' });
|
||||
});
|
||||
|
||||
it('录入卡已确认(done 落了)→ 不再算在等', () => {
|
||||
const done = { at: AT, by: 'S-1', values: { name: '测试公司' } };
|
||||
expect(pendingCardsOf(chat(entry('c-1', { done })))).toEqual({ decision: false, entry: false });
|
||||
});
|
||||
|
||||
it('登记里没有人读名时退回对象地址 —— 宁可笼统,不可编', () => {
|
||||
expect(pendingCardsOf(chat(entry('c-1', { ledgerLabel: undefined }))).entryLedger).toBe('customer.profile');
|
||||
});
|
||||
|
||||
it('未选的决策卡 → decision;它不触发占位页(人要决定的常常就是件上那份稿)', () => {
|
||||
expect(pendingCardsOf(chat(decision('d-1')))).toEqual({ decision: true, entry: false });
|
||||
expect(pendingCardsOf(chat(decision('d-1', { chosen: { at: AT, by: 'S-1', value: 'pass' } })))).toEqual({
|
||||
decision: false,
|
||||
entry: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('两张未回的录入卡:点名最早那一张', () => {
|
||||
const later = entry('c-2', { at: '2026-08-28T01:00:00.000Z', ledgerLabel: '联系人档案' });
|
||||
expect(pendingCardsOf(chat(entry('c-1'), later)).entryLedger).toBe('客户档案');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user