diff --git a/frontends/apps/simple-platform-vue/components.d.ts b/frontends/apps/simple-platform-vue/components.d.ts index 31baef1..b36d5d3 100644 --- a/frontends/apps/simple-platform-vue/components.d.ts +++ b/frontends/apps/simple-platform-vue/components.d.ts @@ -74,6 +74,7 @@ declare module 'vue' { FloatingAlarmCard: typeof import('./src/components/map-monitor/FloatingAlarmCard.vue')['default'] FloatingAlarmStack: typeof import('./src/components/map-monitor/FloatingAlarmStack.vue')['default'] MapMonitorConfigGroup: typeof import('./src/components/config/MapMonitorConfigGroup.vue')['default'] + MissionListPanel: typeof import('./src/components/workbench/MissionListPanel.vue')['default'] MonitorSelectionPanel: typeof import('./src/components/workbench/MonitorSelectionPanel.vue')['default'] PermissionGuard: typeof import('./src/components/PermissionGuard.vue')['default'] PluginListPanel: typeof import('./src/components/reflection/PluginListPanel.vue')['default'] diff --git a/frontends/apps/simple-platform-vue/src/api/delivery.ts b/frontends/apps/simple-platform-vue/src/api/delivery.ts new file mode 100644 index 0000000..be3da13 --- /dev/null +++ b/frontends/apps/simple-platform-vue/src/api/delivery.ts @@ -0,0 +1,36 @@ +import http from './http' +import type { DeliveryTask } from '@/types/delivery' + +const MOCK = import.meta.env.VITE_USE_MOCK === 'true' + +const BASE = '/sl/projection/deliveries' + +export async function listDeliveries(opts?: { + includeFinished?: boolean + includeAborted?: boolean +}): Promise { + if (MOCK) { + const { mockDeliveries } = await import('@/mock/data/deliveries') + return mockDeliveries() + } + const params: Record = {} + if (opts?.includeFinished === false) params.includeFinished = 'false' + if (opts?.includeAborted === false) params.includeAborted = 'false' + const { data } = await http.get(BASE, { params }) + return Array.isArray(data) ? data : [] +} + +export async function cancelDelivery(id: number): Promise { + if (MOCK) return + await http.post(`${BASE}/${id}/cancel`) +} + +export async function resendDelivery(id: number): Promise { + if (MOCK) return + await http.post(`${BASE}/${id}/resend`) +} + +export async function forceCompleteDelivery(id: number): Promise { + if (MOCK) return + await http.post(`${BASE}/${id}/force-complete`) +} diff --git a/frontends/apps/simple-platform-vue/src/components/workbench/MissionListPanel.vue b/frontends/apps/simple-platform-vue/src/components/workbench/MissionListPanel.vue new file mode 100644 index 0000000..330e391 --- /dev/null +++ b/frontends/apps/simple-platform-vue/src/components/workbench/MissionListPanel.vue @@ -0,0 +1,410 @@ + + + + + diff --git a/frontends/apps/simple-platform-vue/src/mock/data/deliveries.ts b/frontends/apps/simple-platform-vue/src/mock/data/deliveries.ts new file mode 100644 index 0000000..85447bf --- /dev/null +++ b/frontends/apps/simple-platform-vue/src/mock/data/deliveries.ts @@ -0,0 +1,58 @@ +import type { DeliveryTask } from '@/types/delivery' + +export async function mockDeliveries(): Promise { + await new Promise((r) => setTimeout(r, 60)) + return [ + { + id: 101, + missionId: 1, + missionName: '链式搬运', + missionTypeName: 'FengTianChainedDeliveryMission', + srcSiteId: 1, + srcLabel: '1-取货台 A', + dstSiteId: 8, + dstLabel: '8-放货台 B', + status: '执行中', + statusCode: 'Fetching', + carId: 1, + carName: 'AGV-01', + priority: 1, + createTime: new Date().toISOString(), + overdue: false + }, + { + id: 102, + missionId: 1, + missionName: '链式搬运', + missionTypeName: 'FengTianChainedDeliveryMission', + srcSiteId: 3, + srcLabel: '3-缓存区', + dstSiteId: 12, + dstLabel: '12-工位 W2', + status: '已下发', + statusCode: 'Waiting', + carId: null, + carName: null, + priority: 0, + createTime: new Date(Date.now() - 45 * 60_000).toISOString(), + overdue: true + }, + { + id: 99, + missionId: 1, + missionName: '链式搬运', + missionTypeName: 'FengTianChainedDeliveryMission', + srcSiteId: 2, + srcLabel: '2-原料区', + dstSiteId: 5, + dstLabel: '5-成品区', + status: '已完成', + statusCode: 'Finished', + carId: 2, + carName: 'AGV-02', + priority: 1, + createTime: new Date(Date.now() - 3600_000).toISOString(), + overdue: false + } + ] +} diff --git a/frontends/apps/simple-platform-vue/src/types/delivery.ts b/frontends/apps/simple-platform-vue/src/types/delivery.ts new file mode 100644 index 0000000..b71f0ec --- /dev/null +++ b/frontends/apps/simple-platform-vue/src/types/delivery.ts @@ -0,0 +1,20 @@ +/** 插件搬运任务(AbstractChainedDeliveryMission.GetDeliveries)投影行 */ +export interface DeliveryTask { + id: number + missionId: number + missionName: string + missionTypeName: string + srcSiteId: number + srcLabel: string + dstSiteId: number + dstLabel: string + status: string + statusCode: string + carId?: number | null + carName?: string | null + priority: number + createTime?: string | null + overdue?: boolean +} + +export type DeliveryAction = 'cancel' | 'resend' | 'force-complete'