From 19ffe847854bb506f243ced2b07fe97538cbeb2c Mon Sep 17 00:00:00 2001 From: zouzhiwen <409053122@qq.com> Date: Mon, 1 Jun 2026 16:30:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=BA=E5=99=A8=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E4=BC=98=E5=8C=96=201.=E4=BB=8E=E6=A5=BC=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=9D=A5=E7=9A=84=E6=89=98=E7=9B=98=E9=9C=80=E8=A6=81=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=AB=99=E8=B5=84=E6=BA=90=202.=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=97=B6=E5=8F=AF=E4=BB=A5=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E8=A7=A3=E7=BB=91=203.=E5=AF=B9=E8=B4=A7?= =?UTF-8?q?=E6=9E=B6=E6=89=98=E7=9B=98=E6=B7=B7=E4=B8=8B=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=8C=89=E6=AF=94=E4=BE=8B=E8=BF=9B=E8=A1=8C=E7=BB=84?= =?UTF-8?q?=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/palletCacheStation.ts | 18 + src/api/task.ts | 4 +- src/layouts/AdminLayout.vue | 12 +- src/router/index.ts | 6 + src/views/station/PalletCacheStationView.vue | 461 +++++++++++++++++++ src/views/task/TaskChainDetail.vue | 61 ++- tsconfig.tsbuildinfo | 2 +- 7 files changed, 550 insertions(+), 14 deletions(-) create mode 100644 src/api/palletCacheStation.ts create mode 100644 src/views/station/PalletCacheStationView.vue diff --git a/src/api/palletCacheStation.ts b/src/api/palletCacheStation.ts new file mode 100644 index 0000000..671fd4e --- /dev/null +++ b/src/api/palletCacheStation.ts @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +export interface PalletCacheStationVO { + warehouse: string + capacity: number + boundCount: number + reservedCount: number + totalCount: number + remainingCapacity: number + reservedChainCodes: string[] +} + +export function getPalletCacheStationSnapshot(warehouse: string) { + return request.get( + '/api/robot/external/admin/pallet-cache-station/snapshot', + { params: { warehouse } }, + ) +} diff --git a/src/api/task.ts b/src/api/task.ts index e3b15d3..01dc048 100644 --- a/src/api/task.ts +++ b/src/api/task.ts @@ -129,11 +129,11 @@ export const taskStatusOptions = [ { value: 'FAILED', label: '失败' }, ] -export function cancelChain(chainCode: string, reason?: string) { +export function cancelChain(chainCode: string, reason?: string, moveOut = false) { return request.post( '/api/robot/external/admin/machine-task/chain/cancel', null, - { params: { chainCode, reason } }, + { params: { chainCode, reason, moveOut } }, ) } diff --git a/src/layouts/AdminLayout.vue b/src/layouts/AdminLayout.vue index 55d7151..a39041d 100644 --- a/src/layouts/AdminLayout.vue +++ b/src/layouts/AdminLayout.vue @@ -31,6 +31,10 @@ + + + + @@ -168,7 +172,7 @@ import { computed, onMounted, onUnmounted, ref, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useUserStore } from '@/stores/user' import { useDevice } from '@/composables/useDevice' -import { Monitor, List, SetUp, Plus, DataLine, Fold, Expand, User, ArrowDown, Refresh, Tickets } from '@element-plus/icons-vue' +import { Monitor, List, SetUp, Plus, DataLine, Fold, Expand, User, ArrowDown, Refresh, Tickets, Box } from '@element-plus/icons-vue' import { useTabsStore } from '@/stores/tabs' const { isMobile } = useDevice() @@ -199,7 +203,7 @@ const userStore = useUserStore() const isMonitorMode = computed(() => userStore.isMonitorMode()) const keepAliveNames = computed(() => { if (isMonitorMode.value) { - return ['TaskChainList', 'TaskChainDetail', 'ElevatorList', 'StationQueueView'] + return ['TaskChainList', 'TaskChainDetail', 'ElevatorList', 'StationQueueView', 'PalletCacheStationView'] } return [ 'DashboardView', @@ -207,6 +211,7 @@ const keepAliveNames = computed(() => { 'TaskChainDetail', 'ElevatorList', 'StationQueueView', + 'PalletCacheStationView', 'VendorLoadView', 'TaskGenerateView', ] @@ -330,6 +335,7 @@ const tabs = computed(() => [ { path: '/task/chain', label: '任务链', icon: List }, { path: '/elevator', label: '提升机', icon: SetUp }, { path: '/station/queue', label: '排队', icon: Tickets }, + { path: '/station/pallet-cache', label: '缓存站', icon: Box }, ...(!isMonitorMode.value ? [{ path: '/vendor/load', label: '厂商负载', icon: DataLine }] : []), ...(!isMonitorMode.value ? [{ path: '/generate', label: '生成', icon: Plus }] : []), ]) @@ -338,6 +344,7 @@ const activeMenu = computed(() => { const path = route.path if (path.startsWith('/task/chain')) return '/task/chain' if (path.startsWith('/station/queue')) return '/station/queue' + if (path.startsWith('/station/pallet-cache')) return '/station/pallet-cache' return path }) @@ -345,6 +352,7 @@ const activeTab = computed(() => { const path = route.path if (path.startsWith('/task/chain')) return '/task/chain' if (path.startsWith('/station/queue')) return '/station/queue' + if (path.startsWith('/station/pallet-cache')) return '/station/pallet-cache' return path }) diff --git a/src/router/index.ts b/src/router/index.ts index 88ee900..da00333 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -52,6 +52,12 @@ const router = createRouter({ component: () => import('@/views/station/StationQueueView.vue'), meta: { title: '站点排队' }, }, + { + path: 'station/pallet-cache', + name: 'PalletCacheStationView', + component: () => import('@/views/station/PalletCacheStationView.vue'), + meta: { title: '托盘缓存站' }, + }, { path: 'vendor/load', name: 'VendorLoadView', diff --git a/src/views/station/PalletCacheStationView.vue b/src/views/station/PalletCacheStationView.vue new file mode 100644 index 0000000..e1d78dc --- /dev/null +++ b/src/views/station/PalletCacheStationView.vue @@ -0,0 +1,461 @@ + + + + + diff --git a/src/views/task/TaskChainDetail.vue b/src/views/task/TaskChainDetail.vue index 4d4b562..f2a3e71 100644 --- a/src/views/task/TaskChainDetail.vue +++ b/src/views/task/TaskChainDetail.vue @@ -390,6 +390,42 @@ + + + + + + + + + + + + + + + + defineOptions({ name: 'TaskChainDetail' }) -import { computed, onMounted, ref } from 'vue' +import { computed, onMounted, reactive, ref } from 'vue' import { useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { ArrowLeft, MoreFilled, VideoPlay, Switch, Delete, House } from '@element-plus/icons-vue' @@ -480,6 +516,11 @@ const route = useRoute() const loading = ref(false) const executing = ref(false) const canceling = ref(false) +const cancelDialogVisible = ref(false) +const cancelForm = reactive({ + reason: '', + moveOut: false, +}) const returningTaskCode = ref(null) const chain = ref(null) const tasks = ref([]) @@ -566,18 +607,20 @@ function onPickStatus(targetStatus: string) { // ==================== 操作逻辑(共用) ==================== async function handleCancelChain() { + if (!chain.value) return + cancelForm.reason = '' + cancelForm.moveOut = false + cancelDialogVisible.value = true +} + +async function submitCancelChain() { if (!chain.value) return try { - const result = await ElMessageBox.prompt('请输入取消原因', '取消任务链', { - confirmButtonText: '确认取消', - cancelButtonText: '返回', - type: 'warning', - inputPlaceholder: '取消原因(可选)', - }) - const reason = (result as { value: string }).value canceling.value = true - await cancelChain(chain.value.code, reason || undefined) + const reason = cancelForm.reason.trim() + await cancelChain(chain.value.code, reason || undefined, cancelForm.moveOut) ElMessage.success('任务链已取消') + cancelDialogVisible.value = false await loadData() } catch { /* cancelled */ } finally { canceling.value = false diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index c7d3fab..89d8463 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/main.ts","./src/api/auth.ts","./src/api/elevator.ts","./src/api/generate.ts","./src/api/stationqueue.ts","./src/api/task.ts","./src/api/vendorload.ts","./src/composables/usedevice.ts","./src/constants/chainstatus.ts","./src/constants/taskstatus.ts","./src/router/index.ts","./src/stores/tabs.ts","./src/stores/user.ts","./src/utils/request.ts","./src/app.vue","./src/layouts/adminlayout.vue","./src/views/dashboard/dashboardview.vue","./src/views/elevator/elevatorlist.vue","./src/views/generate/taskgenerateview.vue","./src/views/login/loginview.vue","./src/views/station/stationqueueview.vue","./src/views/task/taskchaindetail.vue","./src/views/task/taskchainlist.vue","./src/views/vendor/vendorloadview.vue","./env.d.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/main.ts","./src/api/auth.ts","./src/api/elevator.ts","./src/api/generate.ts","./src/api/palletcachestation.ts","./src/api/stationqueue.ts","./src/api/task.ts","./src/api/vendorload.ts","./src/composables/usedevice.ts","./src/constants/chainstatus.ts","./src/constants/taskstatus.ts","./src/router/index.ts","./src/stores/tabs.ts","./src/stores/user.ts","./src/utils/request.ts","./src/app.vue","./src/layouts/adminlayout.vue","./src/views/dashboard/dashboardview.vue","./src/views/elevator/elevatorlist.vue","./src/views/generate/taskgenerateview.vue","./src/views/login/loginview.vue","./src/views/station/palletcachestationview.vue","./src/views/station/stationqueueview.vue","./src/views/task/taskchaindetail.vue","./src/views/task/taskchainlist.vue","./src/views/vendor/vendorloadview.vue","./env.d.ts"],"version":"5.7.3"} \ No newline at end of file