diff --git a/frontend/src/services/dashboardApi.ts b/frontend/src/services/dashboardApi.ts new file mode 100644 index 0000000..4b8e493 --- /dev/null +++ b/frontend/src/services/dashboardApi.ts @@ -0,0 +1,17 @@ +import api from "./api"; + +export interface DashboardStats { + products_total: number; + products_pending: number; + products_in_progress: number; + products_completed: number; + tasks_total: number; + tasks_pending: number; + tasks_in_progress: number; + tasks_completed: number; +} + +export async function fetchDashboardStats(): Promise { + const { data } = await api.get("/dashboard/stats"); + return data; +} diff --git a/frontend/src/services/orderApi.ts b/frontend/src/services/orderApi.ts new file mode 100644 index 0000000..571f2a5 --- /dev/null +++ b/frontend/src/services/orderApi.ts @@ -0,0 +1,12 @@ +import api from "./api"; + +export interface OrderOption { + id: string; + order_no: string; +} + +/** 获取订单列表(供下拉选择) */ +export async function listOrders(): Promise { + const { data } = await api.get("/orders/"); + return data; +} diff --git a/frontend/src/services/productApi.ts b/frontend/src/services/productApi.ts new file mode 100644 index 0000000..82a1c50 --- /dev/null +++ b/frontend/src/services/productApi.ts @@ -0,0 +1,10 @@ +import api from "./api"; +import type { ProductScanResponse } from "../types/api"; + +/** 扫码查询 — 根据 16 位序列号查产品 + 顶层任务 */ +export async function scanProduct(serialNumber: string): Promise { + const { data } = await api.get( + `/products/scan/${encodeURIComponent(serialNumber)}` + ); + return data; +} diff --git a/frontend/src/services/taskApi.ts b/frontend/src/services/taskApi.ts new file mode 100644 index 0000000..0a65a2c --- /dev/null +++ b/frontend/src/services/taskApi.ts @@ -0,0 +1,64 @@ +import api from "./api"; +import type { + TaskResponse, + TaskCompleteResponse, + TaskListResponse, +} from "../types/api"; + +// ============================================================ +// 请求体类型 +// ============================================================ + +export interface SubtaskCreatePayload { + task_name: string; + assignee_id: string | null; + notify_parent_on_complete: boolean; +} + +export interface TaskCompletePayload { + operator_id: string | null; + next_assignee_id: string | null; + next_task_name: string | null; + remark: string | null; +} + +// ============================================================ +// API 方法 +// ============================================================ + +/** 获取任务详情 — 递归包含子任务树 */ +export async function getTask(taskId: string): Promise { + const { data } = await api.get(`/tasks/${taskId}`); + return data; +} + +/** 获取任务列表(可按产品筛选) */ +export async function listTasks(productId?: string): Promise { + const params = productId ? { product_id: productId } : {}; + const { data } = await api.get("/tasks/", { params }); + return data; +} + +/** 创建子任务 */ +export async function createSubtask( + parentTaskId: string, + payload: SubtaskCreatePayload +): Promise { + const { data } = await api.post( + `/tasks/${parentTaskId}/subtasks`, + payload + ); + return data; +} + +/** 完成任务 + 转交 */ +export async function completeTask( + taskId: string, + payload: TaskCompletePayload +): Promise { + const { data } = await api.post( + `/tasks/${taskId}/complete`, + payload + ); + return data; +} diff --git a/frontend/src/types/admin.ts b/frontend/src/types/admin.ts new file mode 100644 index 0000000..fbb29f9 --- /dev/null +++ b/frontend/src/types/admin.ts @@ -0,0 +1,12 @@ +/** 管理端 API 响应类型 */ + +export interface ProductResponse { + id: string; + serial_number: string; + order_id: string; + order_no?: string; + material_id: string | null; + parent_product_id: string | null; + status: string; + created_at: string; +} diff --git a/frontend/src/types/api.ts b/frontend/src/types/api.ts new file mode 100644 index 0000000..e5cc199 --- /dev/null +++ b/frontend/src/types/api.ts @@ -0,0 +1,47 @@ +/** 后端 API 响应类型 */ + +// ============================================================ +// 任务 +// ============================================================ + +export interface TaskSummary { + id: string; + product_id: string; + parent_task_id: string | null; + task_name: string; + assignee_id: string | null; + status: string; + notify_parent_on_complete: boolean; + created_at: string; +} + +export interface TaskResponse extends TaskSummary { + child_tasks: TaskResponse[]; +} + +export interface TaskCompleteResponse { + completed_task: TaskResponse; + next_task: TaskResponse | null; + message: string; +} + +export interface TaskListResponse { + tasks: TaskResponse[]; + total: number; +} + +// ============================================================ +// 产品 +// ============================================================ + +export interface ProductScanResponse { + id: string; + serial_number: string; + order_id: string; + order_no: string; + material_id: string | null; + parent_product_id: string | null; + status: string; + created_at: string; + top_level_tasks: TaskSummary[]; +}