feat: 前端补充生命周期类型定义与工序词表
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
* 供 TaskTreeViewer / TaskListCard / ProductCard 等组件共用,
|
* 供 TaskTreeViewer / TaskListCard / ProductCard 等组件共用,
|
||||||
* 避免在多处重复维护相同的映射逻辑。
|
* 避免在多处重复维护相同的映射逻辑。
|
||||||
*/
|
*/
|
||||||
import { TASK_STATUS } from "../types/api";
|
import { TASK_STATUS, type LifecyclePhase } from "../types/api";
|
||||||
|
|
||||||
export interface StatusStyle {
|
export interface StatusStyle {
|
||||||
bg: string;
|
bg: string;
|
||||||
@ -112,6 +112,19 @@ export const STATUS_CONFIG: Record<string, StatusStyle> = {
|
|||||||
ring: "ring-blue-400",
|
ring: "ring-blue-400",
|
||||||
label: "维修",
|
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 = {
|
const FALLBACK: StatusStyle = {
|
||||||
@ -137,3 +150,100 @@ export function statusColor(status: string): string {
|
|||||||
export function statusLabel(status: string): string {
|
export function statusLabel(status: string): string {
|
||||||
return getStatusConfig(status).label;
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import api from "./api";
|
import api from "./api";
|
||||||
|
import type { LifecyclePhase } from "../types/api";
|
||||||
|
|
||||||
export interface DashboardStats {
|
export interface DashboardStats {
|
||||||
products_total: number;
|
products_total: number;
|
||||||
@ -86,6 +87,8 @@ export interface WipMatrixDetailRow {
|
|||||||
material_name: string;
|
material_name: string;
|
||||||
spec_model: string;
|
spec_model: string;
|
||||||
task_status: string;
|
task_status: string;
|
||||||
|
/** 🔧 生命周期阶段:PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
|
||||||
|
lifecycle_phase?: LifecyclePhase;
|
||||||
assignee_id: string;
|
assignee_id: string;
|
||||||
assignee: string;
|
assignee: string;
|
||||||
duration_hours: number;
|
duration_hours: number;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
/** 管理端 API 响应类型 */
|
/** 管理端 API 响应类型 */
|
||||||
|
import type { LifecyclePhase } from "./api";
|
||||||
|
|
||||||
export interface ProductResponse {
|
export interface ProductResponse {
|
||||||
id: string;
|
id: string;
|
||||||
@ -17,6 +18,8 @@ export interface ProductResponse {
|
|||||||
macro_status: string | null;
|
macro_status: string | null;
|
||||||
overall_status: string | null;
|
overall_status: string | null;
|
||||||
status: string;
|
status: string;
|
||||||
|
/** 🔧 生命周期阶段:PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
|
||||||
|
lifecycle_phase?: LifecyclePhase;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
latest_record_time: string | null;
|
latest_record_time: string | null;
|
||||||
latest_record_content: string | null;
|
latest_record_content: string | null;
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
/** 后端 API 响应类型 */
|
/** 后端 API 响应类型 */
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 生命周期阶段 — 区分「生产阶段的测试(发货测试)」与「出库后返厂(售后维修)」
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
export type LifecyclePhase = "PRODUCTION" | "AFTER_SALES";
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 任务状态常量
|
// 任务状态常量
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@ -97,6 +103,8 @@ export interface ProductScanResponse {
|
|||||||
current_location_id: string | null;
|
current_location_id: string | null;
|
||||||
status: string;
|
status: string;
|
||||||
overall_status: string | null;
|
overall_status: string | null;
|
||||||
|
/** 🔧 生命周期阶段:PRODUCTION(生产制造/发货测试) | AFTER_SALES(出库后返厂售后维修) */
|
||||||
|
lifecycle_phase?: LifecyclePhase;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
top_level_tasks: TaskSummary[];
|
top_level_tasks: TaskSummary[];
|
||||||
/** 完整递归任务树 — 供十字矩阵树状图渲染 */
|
/** 完整递归任务树 — 供十字矩阵树状图渲染 */
|
||||||
|
|||||||
Reference in New Issue
Block a user