Archived
fix(w05): 验收工单的面孔在装配层被丢掉 —— 两头都有测,中间那一段把值扔了
用户实测:「你怎么给我发成了执行工单,我需要的是验收工单,然后标题那一块需要是 验收卡的那种绿色」。 一、面孔:engines.ts 发执行工单那一处是一句写死只认 'data' 的三目,配方递下来的 'accept' 静默丢掉 —— 对话区照旧摆「执行工单」。**配方那一头有测(variant 原样递出去)、 前端那一头有测(accept 该穿哪副面孔)、e2e 按标题驱动也全绿,唯独中间没有。** 修:抽成纯函数 executionCardVariant(与旁边 decisionCardFace 同一种做法、同一个测试位), 认 data / accept、拒 review、认不出的当没写;4 测变异验证过。 e2e 同批改**认面孔不认标题**(试跑观测面的 cards 补 variant,契约变更)—— 标题是活动自己写的字符串,卡穿哪副面孔由装配层决定,那一次正是两者对不上。 二、颜色:件① 验收工单那一副整套强调色换成验收绿 #0aa294(令牌从 ACCENT_LEDGER 现改选择器得来,与件②③、对话区验收卡一处真源),题头那条写死的浅蓝渐变单独给一条绿的; 数据工单那一副仍是蓝。真渲染核过两副 class 与两套令牌。 验收:e2e w05 5/5 released、被拒 0(面孔断言这一轮真在跑);2563 测、四门禁绿; 2.16.0 装库。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -1834,6 +1834,20 @@
|
|||||||
.dossiers 三列网格(1fr·76px·1fr),中间列是实体动画道 —— ⇄ 徽呼吸 + 双点绕徽轨道
|
.dossiers 三列网格(1fr·76px·1fr),中间列是实体动画道 —— ⇄ 徽呼吸 + 双点绕徽轨道
|
||||||
对转(sw-orbit),总线虚线在道里连两卡;窄屏单列收道。浏览器两帧相位实证。
|
对转(sw-orbit),总线虚线在道里连两卡;窄屏单列收道。浏览器两帧相位实证。
|
||||||
|
|
||||||
|
- **「你怎么给我发成了执行工单」—— 面孔在真发卡那条路上被丢掉**(2026-08-31 用户实测,
|
||||||
|
`part-substitution-assessment@2.16.0`):装配层发执行工单那一处是一句**写死只认 `'data'`**
|
||||||
|
的三目(`engines.ts`),配方递下来的 `variant: 'accept'` 静默丢掉 —— 对话区照旧摆「执行工单」。
|
||||||
|
**两头都有测,唯独中间没有**:配方那一头断言了「variant 原样递出去」,前端那一头断言了
|
||||||
|
「accept 该穿哪副面孔」,e2e 按卡的**标题**驱动也照样全绿 —— 三处都对,而它们中间那一段把值扔了。
|
||||||
|
修:抽成纯函数 `executionCardVariant`(与旁边的 `decisionCardFace` 同一种做法、同一个测试位),
|
||||||
|
认 data / accept、拒 review、认不出的当没写;新测 4 条变异验证过。
|
||||||
|
e2e 同批**改认面孔不认标题**(试跑观测面的 `cards` 补 `variant`,契约变更):标题是活动自己写的
|
||||||
|
字符串,卡穿哪副面孔由装配层决定,两者可以对不上 —— 那一次正是「标题叫验收工单、发出去是执行工单」。
|
||||||
|
**面孔要在真发卡那条路上断言。**
|
||||||
|
同批(用户第二句「标题那一块需要是验收卡的那种绿色」):件① 验收工单那一副整套强调色换成
|
||||||
|
**验收绿 #0aa294**(令牌从 `ACCENT_LEDGER` 现改选择器得来,数值与件②③、对话区验收卡一处真源),
|
||||||
|
题头那条写死的浅蓝渐变单独给一条绿的;数据工单那一副仍是蓝。真渲染核过两副 class 与两套令牌。
|
||||||
|
|
||||||
- **起单不许选到同一颗料;S1 数据齐了也叫人一次**(2026-08-31 用户两条,
|
- **起单不许选到同一颗料;S1 数据齐了也叫人一次**(2026-08-31 用户两条,
|
||||||
`part-substitution-assessment@2.15.0`):
|
`part-substitution-assessment@2.15.0`):
|
||||||
①**两格互斥**(「创建活动的启动参数里面不应该能选到同样的两个芯片」)—— 查下来不只是没意义,
|
①**两格互斥**(「创建活动的启动参数里面不应该能选到同样的两个芯片」)—— 查下来不只是没意义,
|
||||||
|
|||||||
@@ -864,6 +864,21 @@ describe('件① 评估输入补全', () => {
|
|||||||
expect(colOf('sub_eval.case', 'order_kind')?.tally).toEqual(['data', 'accept']);
|
expect(colOf('sub_eval.case', 'order_kind')?.tally).toEqual(['data', 'accept']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2026-08-31 用户:「标题那一块需要是验收卡的那种绿色」—— 验收工单那一副整套强调色换成
|
||||||
|
* 验收绿 #0aa294(与件②③、对话区验收卡同一枚),题头那条写死的浅蓝渐变单独给一条绿的。
|
||||||
|
* 令牌从 `ACCENT_LEDGER` 现改选择器得来:**数值只有一处真源**,件②③ 改色时这一副跟着走。
|
||||||
|
*/
|
||||||
|
it('验收工单那一副是验收绿:整套令牌换成 #0aa294,题头渐变也换掉(数值与件②③ 同源)', () => {
|
||||||
|
expect(html).toContain('.card.v-accept{');
|
||||||
|
expect(html).toContain('.card.v-accept.hd-light .card-head{background:linear-gradient(');
|
||||||
|
/* 蓝那一套仍在(数据工单那一副),两套各就各位 */
|
||||||
|
expect(html).toContain('--acc:#2e6bff');
|
||||||
|
const acceptBlock = html.slice(html.indexOf('.card.v-accept{'), html.indexOf('.card.v-accept.hd-light'));
|
||||||
|
expect(acceptBlock).toContain('--acc:#0aa294');
|
||||||
|
expect(acceptBlock).toContain('--ledger:#0aa294');
|
||||||
|
});
|
||||||
|
|
||||||
it('缺项点名全并进顶条「还差什么」,正文不再有逐块红带', () => {
|
it('缺项点名全并进顶条「还差什么」,正文不再有逐块红带', () => {
|
||||||
expect(html).toContain('class="jc-gate-sub" data-class-of="parts_profile_missing"');
|
expect(html).toContain('class="jc-gate-sub" data-class-of="parts_profile_missing"');
|
||||||
expect(html).toContain('data-slot="parts_profile_missing_keys"');
|
expect(html).toContain('data-slot="parts_profile_missing_keys"');
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const manifest: ActivityManifest = {
|
|||||||
activityId: ACTIVITY_ID,
|
activityId: ACTIVITY_ID,
|
||||||
name: 'ACT-WORK-05 · 差异评估',
|
name: 'ACT-WORK-05 · 差异评估',
|
||||||
/* 重写不是改 —— 同版重装是 no-op(静默丢失,踩过) */
|
/* 重写不是改 —— 同版重装是 no-op(静默丢失,踩过) */
|
||||||
packageVersion: '2.15.0',
|
packageVersion: '2.16.0',
|
||||||
category: '需求分析与方案匹配',
|
category: '需求分析与方案匹配',
|
||||||
sdkVersion: '0.1.0-m5',
|
sdkVersion: '0.1.0-m5',
|
||||||
checksum: 'dev-checksum-part-substitution-assessment',
|
checksum: 'dev-checksum-part-substitution-assessment',
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
* 印章 hero + 落账去向 + 四态计数与硬约束点名 + 待验项。
|
* 印章 hero + 落账去向 + 四态计数与硬约束点名 + 待验项。
|
||||||
*/
|
*/
|
||||||
import { vtok, badgeCss } from './badge.ts';
|
import { vtok, badgeCss } from './badge.ts';
|
||||||
import { SHELL_CSS, ACCENT_DATA, ACCENT_LEDGER } from './style.ts';
|
import { SHELL_CSS, ACCENT_DATA, ACCENT_LEDGER, ACCENT_ACCEPT } from './style.ts';
|
||||||
import { D } from '../constants.ts';
|
import { D } from '../constants.ts';
|
||||||
|
|
||||||
/* ==================== 徽标配色(值与文案成对交给 badgeCss,选择器从值算,不手写) ==================== */
|
/* ==================== 徽标配色(值与文案成对交给 badgeCss,选择器从值算,不手写) ==================== */
|
||||||
@@ -205,6 +205,7 @@ ${badgeCss('.rl', [
|
|||||||
.v-accept .k-data { display: none; }
|
.v-accept .k-data { display: none; }
|
||||||
.v-accept .k-acc { display: inline; }
|
.v-accept .k-acc { display: inline; }
|
||||||
.v-accept .fabs { display: none; }
|
.v-accept .fabs { display: none; }
|
||||||
|
${ACCENT_ACCEPT}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ export const ACCENT_LEDGER = `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **验收工单那一副的强调色**(2026-08-31 用户:「标题那一块需要是验收卡的那种绿色」)——
|
||||||
|
* 件① 一张两副面孔:数据工单蓝、验收工单绿。整套令牌从 `ACCENT_LEDGER` **现改选择器**得来,
|
||||||
|
* 数值只有一处真源(件②③ 与对话区验收卡同一枚 #0aa294);题头那条浅色渐变是写死的蓝白,
|
||||||
|
* 单独给一条绿的override —— `.card.v-accept`(0,2,0)比 `:root`(0,1,0)特异,先后顺序不吃亏。
|
||||||
|
*/
|
||||||
|
export const ACCENT_ACCEPT = `${ACCENT_LEDGER.replace(':root{', '.card.v-accept{')}
|
||||||
|
.card.v-accept.hd-light .card-head{background:linear-gradient(120deg,#e9f9f5 0%,#fff 55%,#e3f7f1 100%);border-bottom-color:var(--acc-deep)}
|
||||||
|
`;
|
||||||
|
|
||||||
export const SHELL_CSS = `
|
export const SHELL_CSS = `
|
||||||
/* ================= 令牌与底 ================= */
|
/* ================= 令牌与底 ================= */
|
||||||
:root{
|
:root{
|
||||||
|
|||||||
@@ -2835,6 +2835,10 @@ export declare const testActivityStateRoute: {
|
|||||||
execution: "execution";
|
execution: "execution";
|
||||||
acceptance: "acceptance";
|
acceptance: "acceptance";
|
||||||
}>;
|
}>;
|
||||||
|
variant: z.ZodOptional<z.ZodEnum<{
|
||||||
|
data: "data";
|
||||||
|
accept: "accept";
|
||||||
|
}>>;
|
||||||
title: z.ZodString;
|
title: z.ZodString;
|
||||||
done: z.ZodBoolean;
|
done: z.ZodBoolean;
|
||||||
result: z.ZodOptional<z.ZodString>;
|
result: z.ZodOptional<z.ZodString>;
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* **执行工单的面孔在装配层这一处定**(2026-08-31,用户实测:「你怎么给我发成了执行工单,
|
||||||
|
* 我需要的是验收工单」)。
|
||||||
|
*
|
||||||
|
* 病:配方递下来 `variant: 'accept'`(验收工单 —— 件只读、人只确认),而装配层这一处
|
||||||
|
* 是一句写死只认 `'data'` 的三目,别的值**静默丢掉** —— 对话区照旧摆「执行工单」。
|
||||||
|
*
|
||||||
|
* 更值得记的是**两头都有测,唯独中间没有**:配方那一头断言了「variant 原样递出去」,
|
||||||
|
* 前端那一头断言了「accept 该穿哪副面孔」,e2e 按卡的**标题**驱动也照样绿 ——
|
||||||
|
* 三处都对,而它们中间这一段把值扔了。**面孔要在真发卡那条路上断言。**
|
||||||
|
*/
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { executionCardVariant } from '../wiring/engines.ts';
|
||||||
|
|
||||||
|
describe('执行工单的两副变体面孔', () => {
|
||||||
|
it('data 数据工单 / accept 验收工单,两个都认', () => {
|
||||||
|
expect(executionCardVariant('data', undefined)).toBe('data');
|
||||||
|
expect(executionCardVariant('accept', undefined)).toBe('accept');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('剧本声明优先于卡骨架 —— 模型抄卡会把 variant 抄丢(2026-08-27 实测)', () => {
|
||||||
|
expect(executionCardVariant(undefined, 'data')).toBe('data');
|
||||||
|
expect(executionCardVariant('data', 'accept')).toBe('accept');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('`review` 是决策卡那一路的面孔,不许串到执行工单上', () => {
|
||||||
|
expect(executionCardVariant('review', undefined)).toBeUndefined();
|
||||||
|
expect(executionCardVariant(undefined, 'review')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('没写 / 认不出的值:普通执行工单,不把脏东西端下去', () => {
|
||||||
|
expect(executionCardVariant(undefined, undefined)).toBeUndefined();
|
||||||
|
expect(executionCardVariant('', undefined)).toBeUndefined();
|
||||||
|
expect(executionCardVariant({ variant: 'accept' }, undefined)).toBeUndefined();
|
||||||
|
expect(executionCardVariant(42, undefined)).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -712,6 +712,7 @@ export function registerGovernanceOpsRoutes(app: Hono<AppEnv>, container: Contai
|
|||||||
cards: orders.map((o) => ({
|
cards: orders.map((o) => ({
|
||||||
id: o.id,
|
id: o.id,
|
||||||
mode: o.mode,
|
mode: o.mode,
|
||||||
|
...(o.mode === 'execution' && o.variant !== undefined ? { variant: o.variant } : {}),
|
||||||
title: o.title,
|
title: o.title,
|
||||||
done: o.done !== undefined,
|
done: o.done !== undefined,
|
||||||
...(o.done?.result === undefined ? {} : { result: String(o.done.result) }),
|
...(o.done?.result === undefined ? {} : { result: String(o.done.result) }),
|
||||||
|
|||||||
@@ -242,6 +242,27 @@ export function createOnlyViolation(
|
|||||||
* 而 `checkChatCardReply` 又要求 `checked ⊇ checklist`:卡按不下去。**只在 `reviewFace` 为真时**
|
* 而 `checkChatCardReply` 又要求 `checked ⊇ checklist`:卡按不下去。**只在 `reviewFace` 为真时**
|
||||||
* 才退回剧本声明的清单 —— 非审核面孔的卡,清单就是没有,不发明一条按不下去的。
|
* 才退回剧本声明的清单 —— 非审核面孔的卡,清单就是没有,不发明一条按不下去的。
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* **执行工单的面孔** —— 两副变体:`data` 数据工单(件上的表就是要建的记录,确认即入库)/
|
||||||
|
* `accept` 验收工单(件只读,人只核对确认)。`review` 是决策卡那一路的面孔,不许串到这儿来;
|
||||||
|
* 认不出的值一律当没写(普通执行工单),不把脏东西端下去。
|
||||||
|
*
|
||||||
|
* **剧本声明(`PlanStep.cardVariant`)优先于卡骨架**:模型抄卡时会把 `variant` 抄丢
|
||||||
|
* (2026-08-27 实测:同一张卡 gateLedgers 抄到了、variant 没有)。但卡自己带的值同样作数 ——
|
||||||
|
* 配方那一路没有模型可抄丢,而**一个步骤里两笔条件互斥的 card**(缺东西派数据工单 /
|
||||||
|
* 都齐了派验收工单,2026-08-31)本来就不可能由一个 step 级的 `cardVariant` 说清。
|
||||||
|
*
|
||||||
|
* **这一处此前是内联的三目,写死只认 `'data'`**(2026-08-31 用户实测:「你怎么给我发成了
|
||||||
|
* 执行工单」)—— 配方递下来的 `accept` 在这儿被静默丢掉,对话区照旧摆「执行工单」。
|
||||||
|
* 配方那一头与前端那一头都有测,唯独**真发卡这条路**上没有:面孔要在这里断言。
|
||||||
|
*/
|
||||||
|
export function executionCardVariant(fromCard: unknown, fromStep: unknown): 'data' | 'accept' | undefined {
|
||||||
|
for (const value of [fromStep, fromCard]) {
|
||||||
|
if (value === 'data' || value === 'accept') return value;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function decisionCardFace(
|
export function decisionCardFace(
|
||||||
input: { readonly variant?: 'review' | undefined; readonly checklist?: ReadonlyArray<string> | undefined },
|
input: { readonly variant?: 'review' | undefined; readonly checklist?: ReadonlyArray<string> | undefined },
|
||||||
step: { readonly cardVariant?: string | undefined; readonly acceptanceChecklist?: ReadonlyArray<string> | undefined } | undefined,
|
step: { readonly cardVariant?: string | undefined; readonly acceptanceChecklist?: ReadonlyArray<string> | undefined } | undefined,
|
||||||
@@ -1913,8 +1934,7 @@ export function wireEngines(deps: EngineWiringDeps): EngineWiring {
|
|||||||
: (await deps.registry.manifestOf((await taskContext.of(input.taskId)).activityId)).assets.businessModel.steps?.find(
|
: (await deps.registry.manifestOf((await taskContext.of(input.taskId)).activityId)).assets.businessModel.steps?.find(
|
||||||
(s) => s.item === input.itemId,
|
(s) => s.item === input.itemId,
|
||||||
)?.cardVariant;
|
)?.cardVariant;
|
||||||
// 执行工单这一路只认 data(review 是决策卡那一路的面孔)
|
const variant = executionCardVariant(input.card['variant'], stepVariant);
|
||||||
const variant = stepVariant === 'data' || input.card['variant'] === 'data' ? ('data' as const) : undefined;
|
|
||||||
const issued = await deps.humanTool.issueExecution(context, {
|
const issued = await deps.humanTool.issueExecution(context, {
|
||||||
title,
|
title,
|
||||||
basis: basis.length > 0 ? basis : [{ k: '来源', v: '案例模型当下局面' }],
|
basis: basis.length > 0 ? basis : [{ k: '来源', v: '案例模型当下局面' }],
|
||||||
|
|||||||
@@ -1060,6 +1060,13 @@ export const testActivityStateRoute = {
|
|||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
mode: z.enum(['execution', 'acceptance']),
|
mode: z.enum(['execution', 'acceptance']),
|
||||||
|
/**
|
||||||
|
* 执行工单的**面孔**:`data` 数据工单 / `accept` 验收工单(2026-08-31 补)。
|
||||||
|
* 观测面得看得见这张卡是以什么身份发出去的 —— 面孔在装配层那一处决定,
|
||||||
|
* 而它此前恰恰因为「配方那头与前端那头都有测、中间没有」漏过一次
|
||||||
|
* (配方递 `accept`,装配层写死只认 `data`,人收到的是「执行工单」)。
|
||||||
|
*/
|
||||||
|
variant: z.enum(['data', 'accept']).optional(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
done: z.boolean(),
|
done: z.boolean(),
|
||||||
result: z.string().optional(),
|
result: z.string().optional(),
|
||||||
|
|||||||
+17
-1
@@ -1335,6 +1335,8 @@ async function runCase(suite, kase) {
|
|||||||
let dataCardSeen = false;
|
let dataCardSeen = false;
|
||||||
/** w05「都在库」:匹配**验收工单**那一段的执行卡出现过 —— 数据齐了也要叫人一次 */
|
/** w05「都在库」:匹配**验收工单**那一段的执行卡出现过 —— 数据齐了也要叫人一次 */
|
||||||
let acceptCardSeen = false;
|
let acceptCardSeen = false;
|
||||||
|
/** 那张卡的**面孔**不对(标题是验收工单,发出去却是执行工单)—— 2026-08-31 真撞过一次 */
|
||||||
|
let acceptFaceWrong = false;
|
||||||
/** w05「类型不一致·硬拦」:`sub_eval.case.gate_reason` 命中过 `kase.expectGateReason` 那个词 */
|
/** w05「类型不一致·硬拦」:`sub_eval.case.gate_reason` 命中过 `kase.expectGateReason` 那个词 */
|
||||||
let gateReasonMatched = false;
|
let gateReasonMatched = false;
|
||||||
/** `kase.customFill` 只跑一次(w05「候选缺库·新建类型」:两阶段写 —— 先铸 type_id,读回来再引用它) */
|
/** `kase.customFill` 只跑一次(w05「候选缺库·新建类型」:两阶段写 —— 先铸 type_id,读回来再引用它) */
|
||||||
@@ -1419,7 +1421,20 @@ async function runCase(suite, kase) {
|
|||||||
dataCardSeen = (body.cards ?? []).some((c) => (suite.stages ?? []).some((s) => s.kind !== 'accept' && s.match.test(c.title ?? '')));
|
dataCardSeen = (body.cards ?? []).some((c) => (suite.stages ?? []).some((s) => s.kind !== 'accept' && s.match.test(c.title ?? '')));
|
||||||
}
|
}
|
||||||
if (kase.expectAcceptCard && !acceptCardSeen) {
|
if (kase.expectAcceptCard && !acceptCardSeen) {
|
||||||
acceptCardSeen = (body.cards ?? []).some((c) => (suite.stages ?? []).some((s) => s.kind === 'accept' && s.match.test(c.title ?? '')));
|
/*
|
||||||
|
* **认面孔,不认标题**(2026-08-31 用户实测:「你怎么给我发成了执行工单」)——
|
||||||
|
* 标题是活动自己写的字符串,卡穿的是哪副面孔由装配层决定,两者可以对不上:
|
||||||
|
* 那一次配方递了 `accept`、标题也叫「验收工单 · …」,而装配层把 variant 丢了,
|
||||||
|
* 人收到的是一张执行工单 —— 按标题驱动的这套脚本当时照样全绿。
|
||||||
|
*/
|
||||||
|
const seen = (body.cards ?? []).find((c) => (suite.stages ?? []).some((s) => s.kind === 'accept' && s.match.test(c.title ?? '')));
|
||||||
|
if (seen !== undefined) {
|
||||||
|
acceptCardSeen = true;
|
||||||
|
if (seen.variant !== 'accept') {
|
||||||
|
console.log(` ⚠️ 这张卡的标题是验收工单,发出去穿的却是「${seen.variant ?? '执行工单'}」的面孔 —— 判失败`);
|
||||||
|
acceptFaceWrong = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// w05「类型不一致·硬拦」:gate_reason 那句话要点了名(latch 住,答完卡草稿就清了,过了这一拍再查就晚了)
|
// w05「类型不一致·硬拦」:gate_reason 那句话要点了名(latch 住,答完卡草稿就清了,过了这一拍再查就晚了)
|
||||||
if (kase.expectGateReason && !gateReasonMatched) {
|
if (kase.expectGateReason && !gateReasonMatched) {
|
||||||
@@ -1663,6 +1678,7 @@ async function runCase(suite, kase) {
|
|||||||
console.log(' ⚠️ 数据齐了也该叫人一次(只读的验收工单),一张都没见到 —— 判失败(多半是 S1 又被拍首的 doneWhen 扫描收掉了)');
|
console.log(' ⚠️ 数据齐了也该叫人一次(只读的验收工单),一张都没见到 —— 判失败(多半是 S1 又被拍首的 doneWhen 扫描收掉了)');
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
if (acceptFaceWrong) ok = false;
|
||||||
if (kase.expectGateReason && !gateReasonMatched) {
|
if (kase.expectGateReason && !gateReasonMatched) {
|
||||||
console.log(` ⚠️ gate_reason 没点名(期望命中 ${kase.expectGateReason})—— 判失败`);
|
console.log(` ⚠️ gate_reason 没点名(期望命中 ${kase.expectGateReason})—— 判失败`);
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user