From 2b5e3ae4c3ddc56b1f5580b16e7564a1d0483376 Mon Sep 17 00:00:00 2001 From: duxingchen Date: Tue, 4 Aug 2026 17:30:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=9B=B4=E6=96=B0=20TS=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89=E4=B8=8E=20API=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=B1=82=EF=BC=8C=E5=AF=B9=E6=8E=A5=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit types/api.ts: - TaskSummary/TaskResponse 新增 is_rework, reject_reason, received_at, completed_at 字段 - 新增 TASK_STATUS 常量 (PENDING/WIP/COMPLETED/REJECTED/ARCHIVED) - 新增 TaskTransferResponse, TaskRejectPayload, TaskTransferPayload 类型 - ProductScanResponse 新增 current_location_id, task_tree 字段 types/admin.ts: - ProductResponse 新增 current_location_id 字段 services/taskApi.ts: - 新增 getTaskTree(serialNumber) — 产品全景任务树 - 新增 receiveTask(taskId) — 确认接收 - 新增 rejectTask(taskId, reason) — 品质驳回 - 新增 transferTask(taskId, assignees, name, note?) — 完工裂变转交 --- frontend/src/services/taskApi.ts | 68 +++++++++++++++++++++++++++++++- frontend/src/types/admin.ts | 1 + frontend/src/types/api.ts | 43 +++++++++++++++++++- 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/frontend/src/services/taskApi.ts b/frontend/src/services/taskApi.ts index 0a65a2c..a94ecc7 100644 --- a/frontend/src/services/taskApi.ts +++ b/frontend/src/services/taskApi.ts @@ -2,7 +2,11 @@ import api from "./api"; import type { TaskResponse, TaskCompleteResponse, + TaskTransferResponse, TaskListResponse, + ProductScanResponse, + TaskRejectPayload, + TaskTransferPayload, } from "../types/api"; // ============================================================ @@ -51,7 +55,7 @@ export async function createSubtask( return data; } -/** 完成任务 + 转交 */ +/** 完成任务 + 转交(旧版单步) */ export async function completeTask( taskId: string, payload: TaskCompletePayload @@ -62,3 +66,65 @@ export async function completeTask( ); return data; } + +// ============================================================ +// 新版核心业务 API(重构后) +// ============================================================ + +/** + * 获取产品全景任务树 — 用于十字矩阵树状图。 + * 对应后端 GET /api/v1/products/scan/{serialNumber} + */ +export async function getTaskTree( + serialNumber: string +): Promise { + const { data } = await api.get( + `/products/scan/${encodeURIComponent(serialNumber)}` + ); + return data; +} + +/** + * 确认接收任务 — PENDING → WIP。 + * 对应后端 POST /api/v1/tasks/{taskId}/receive + */ +export async function receiveTask(taskId: string): Promise { + const { data } = await api.post(`/tasks/${taskId}/receive`); + return data; +} + +/** + * 品质驳回 — → REJECTED,后端自动创建返工任务。 + * 对应后端 POST /api/v1/tasks/{taskId}/reject + */ +export async function rejectTask( + taskId: string, + reason: string +): Promise { + const { data } = await api.post( + `/tasks/${taskId}/reject`, + { reason } satisfies TaskRejectPayload + ); + return data; +} + +/** + * 完工裂变转交 — → COMPLETED,批量创建下家任务。 + * 对应后端 POST /api/v1/tasks/{taskId}/transfer + */ +export async function transferTask( + taskId: string, + nextAssignees: string[], + nextTaskName: string, + note?: string +): Promise { + const { data } = await api.post( + `/tasks/${taskId}/transfer`, + { + next_assignees: nextAssignees, + next_task_name: nextTaskName, + note, + } satisfies TaskTransferPayload + ); + return data; +} diff --git a/frontend/src/types/admin.ts b/frontend/src/types/admin.ts index fbb29f9..473341d 100644 --- a/frontend/src/types/admin.ts +++ b/frontend/src/types/admin.ts @@ -7,6 +7,7 @@ export interface ProductResponse { order_no?: string; material_id: string | null; parent_product_id: string | null; + current_location_id: string | null; status: string; created_at: string; } diff --git a/frontend/src/types/api.ts b/frontend/src/types/api.ts index e5cc199..a7328d8 100644 --- a/frontend/src/types/api.ts +++ b/frontend/src/types/api.ts @@ -1,5 +1,19 @@ /** 后端 API 响应类型 */ +// ============================================================ +// 任务状态常量 +// ============================================================ + +export const TASK_STATUS = { + PENDING: "PENDING", + WIP: "WIP", + COMPLETED: "COMPLETED", + REJECTED: "REJECTED", + ARCHIVED: "ARCHIVED", +} as const; + +export type TaskStatus = (typeof TASK_STATUS)[keyof typeof TASK_STATUS]; + // ============================================================ // 任务 // ============================================================ @@ -10,8 +24,12 @@ export interface TaskSummary { parent_task_id: string | null; task_name: string; assignee_id: string | null; - status: string; + status: TaskStatus | string; notify_parent_on_complete: boolean; + is_rework: boolean; + reject_reason: string | null; + received_at: string | null; + completed_at: string | null; created_at: string; } @@ -19,17 +37,37 @@ export interface TaskResponse extends TaskSummary { child_tasks: TaskResponse[]; } +// ---- 操作响应 ---- + export interface TaskCompleteResponse { completed_task: TaskResponse; next_task: TaskResponse | null; message: string; } +export interface TaskTransferResponse { + completed_task: TaskResponse; + created_tasks: TaskResponse[]; + message: string; +} + export interface TaskListResponse { tasks: TaskResponse[]; total: number; } +// ---- 请求体 ---- + +export interface TaskRejectPayload { + reason: string; +} + +export interface TaskTransferPayload { + next_assignees: string[]; + next_task_name: string; + note?: string; +} + // ============================================================ // 产品 // ============================================================ @@ -41,7 +79,10 @@ export interface ProductScanResponse { order_no: string; material_id: string | null; parent_product_id: string | null; + current_location_id: string | null; status: string; created_at: string; top_level_tasks: TaskSummary[]; + /** 完整递归任务树 — 供十字矩阵树状图渲染 */ + task_tree: TaskResponse[]; }