feat: 前端补充生命周期类型定义与工序词表

This commit is contained in:
2026-09-14 14:49:38 +08:00
parent 2de95799c6
commit db3bafcc66
4 changed files with 125 additions and 1 deletions

View File

@ -4,7 +4,7 @@
* 供 TaskTreeViewer / TaskListCard / ProductCard 等组件共用,
* 避免在多处重复维护相同的映射逻辑。
*/
import { TASK_STATUS } from "../types/api";
import { TASK_STATUS, type LifecyclePhase } from "../types/api";
export interface StatusStyle {
bg: string;
@ -112,6 +112,19 @@ export const STATUS_CONFIG: Record<string, StatusStyle> = {
ring: "ring-blue-400",
label: "维修",
},
// ---- 售后回流阶段专属工序(红系,与生产阶段一眼区分)----
: {
bg: "bg-red-50",
text: "text-red-700",
ring: "ring-red-400",
label: "发货测试",
},
: {
bg: "bg-red-50",
text: "text-red-700",
ring: "ring-red-400",
label: "售后维修",
},
};
const FALLBACK: StatusStyle = {
@ -137,3 +150,100 @@ export function statusColor(status: string): string {
export function statusLabel(status: string): string {
return getStatusConfig(status).label;
}
// ============================================================
// 🔧 生命周期阶段lifecycle_phase与工序选项隔离
//
// 生产制造PRODUCTION与售后回流AFTER_SALES各有一套合法工序名。
// ⚠️ 本段与后端 app/core/lifecycle.py 是同一份口径,改动请两边同步。
//
// 售后阶段使用**独立工序名**(发货测试 / 售后维修),不复用生产阶段的
// 「测试 / 维修」—— 这样看板、下钻、导出无需 JOIN lifecycle_phase 即可区分。
// ============================================================
export const LIFECYCLE_PHASE = {
PRODUCTION: "PRODUCTION",
AFTER_SALES: "AFTER_SALES",
} as const satisfies Record<string, LifecyclePhase>;
/** 售后专属工序名 — 选中即代表设备进入售后生命周期 */
export const STEP_SHIP_TEST = "发货测试";
export const STEP_AFTER_SALES_REPAIR = "售后维修";
const AFTER_SALES_ONLY_STEPS = [STEP_SHIP_TEST, STEP_AFTER_SALES_REPAIR];
// ── 生产制造阶段合法工序(原有词表,一字未改)──
export const PRODUCTION_TASK_OPTIONS = ["备货", "生产", "测试", "维修", "在库"];
export const PRODUCTION_OVERALL_OPTIONS = [
"备货", "生产", "测试", "维修", "在库", "已入库", "已出库",
];
// ── 售后回流阶段合法工序:只保留「发货测试 / 售后维修 / 入库出库」──
export const AFTER_SALES_TASK_OPTIONS = [STEP_SHIP_TEST, STEP_AFTER_SALES_REPAIR, "在库"];
export const AFTER_SALES_OVERALL_OPTIONS = [
STEP_SHIP_TEST, STEP_AFTER_SALES_REPAIR, "在库", "已入库", "已出库",
];
/**
* 按生命周期阶段取「可选工序」——选项隔离的 UI 侧实现。
*
* hasHistory = false无任何历史任务的首次激活 / 老设备)时返回**并集**
* 让操作员自行声明这是生产设备还是售后回流设备:一旦选中售后专属工序,
* 后端即把设备判为 AFTER_SALES之后下拉就只剩售后选项。
*
* 注意:这只是体验层的第一道防线,真正的拦截在后端
* task_service._enforce_step_isolation防伪造传参
*/
export function taskOptionsFor(
phase: string | null | undefined,
hasHistory = true,
): string[] {
if (phase === LIFECYCLE_PHASE.AFTER_SALES) return AFTER_SALES_TASK_OPTIONS;
if (!hasHistory) return [...PRODUCTION_TASK_OPTIONS, ...AFTER_SALES_ONLY_STEPS];
return PRODUCTION_TASK_OPTIONS;
}
/** 按生命周期阶段取「可选宏观状态」— 同上,含已入库/已出库等终态 */
export function overallOptionsFor(
phase: string | null | undefined,
hasHistory = true,
): string[] {
if (phase === LIFECYCLE_PHASE.AFTER_SALES) return AFTER_SALES_OVERALL_OPTIONS;
if (!hasHistory) return [...PRODUCTION_OVERALL_OPTIONS, ...AFTER_SALES_ONLY_STEPS];
return PRODUCTION_OVERALL_OPTIONS;
}
/** 列表筛选枚举 — 两阶段并集(用于筛选,不是录入项) */
export const ALL_OVERALL_OPTIONS = [
...PRODUCTION_OVERALL_OPTIONS, ...AFTER_SALES_ONLY_STEPS,
];
/** 售后服务相关环节 — 只有落到这些工序才打红色标签 */
const AFTER_SALES_TAG_STEPS = new Set<string>(AFTER_SALES_ONLY_STEPS);
export interface LifecycleBadge {
label: string;
className: string;
phase: LifecyclePhase;
}
/**
* 生命周期标签 — 只在设备确实处于**售后回流环节**时返回:
* 生命周期为 AFTER_SALES 且当前工序是「发货测试」或「售后维修」
* → 红底白字,文案即工序名。
*
* 生产制造阶段一律返回 null不打标避免和售后设备混淆。
*/
export function lifecycleBadge(
overallStatus: string | null | undefined,
phase: string | null | undefined,
): LifecycleBadge | null {
if (phase !== LIFECYCLE_PHASE.AFTER_SALES) return null;
const step = (overallStatus || "").trim();
if (!AFTER_SALES_TAG_STEPS.has(step)) return null;
return {
label: step,
className: "bg-red-600 text-white ring-1 ring-red-600",
phase: LIFECYCLE_PHASE.AFTER_SALES,
};
}

View File

@ -1,4 +1,5 @@
import api from "./api";
import type { LifecyclePhase } from "../types/api";
export interface DashboardStats {
products_total: number;
@ -86,6 +87,8 @@ export interface WipMatrixDetailRow {
material_name: string;
spec_model: string;
task_status: string;
/** 🔧 生命周期阶段PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
lifecycle_phase?: LifecyclePhase;
assignee_id: string;
assignee: string;
duration_hours: number;

View File

@ -1,4 +1,5 @@
/** 管理端 API 响应类型 */
import type { LifecyclePhase } from "./api";
export interface ProductResponse {
id: string;
@ -17,6 +18,8 @@ export interface ProductResponse {
macro_status: string | null;
overall_status: string | null;
status: string;
/** 🔧 生命周期阶段PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
lifecycle_phase?: LifecyclePhase;
created_at: string;
latest_record_time: string | null;
latest_record_content: string | null;

View File

@ -1,5 +1,11 @@
/** 后端 API 响应类型 */
// ============================================================
// 生命周期阶段 — 区分「生产阶段的测试(发货测试)」与「出库后返厂(售后维修)」
// ============================================================
export type LifecyclePhase = "PRODUCTION" | "AFTER_SALES";
// ============================================================
// 任务状态常量
// ============================================================
@ -97,6 +103,8 @@ export interface ProductScanResponse {
current_location_id: string | null;
status: string;
overall_status: string | null;
/** 🔧 生命周期阶段PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
lifecycle_phase?: LifecyclePhase;
created_at: string;
top_level_tasks: TaskSummary[];
/** 完整递归任务树 — 供十字矩阵树状图渲染 */