refactor: 调整存储菜单组件的子菜单位置为右上角,简化代码结构,提升可读性

This commit is contained in:
xudan 2025-09-15 10:51:56 +08:00
parent 6c7fcb9eba
commit 6de409bc69

View File

@ -40,21 +40,13 @@
v-if="showSubMenu && selectedLocation" v-if="showSubMenu && selectedLocation"
:open="!!showSubMenu" :open="!!showSubMenu"
:trigger="[]" :trigger="[]"
placement="topRight" placement="rightTop"
:get-popup-container="getSubMenuContainer" :get-popup-container="getSubMenuContainer"
@open-change="handleSubMenuOpenChange" @open-change="handleSubMenuOpenChange"
> >
<div <div ref="subMenuTriggerRef" class="sub-menu-trigger" :style="subMenuTriggerStyle" />
ref="subMenuTriggerRef"
class="sub-menu-trigger"
:style="subMenuTriggerStyle"
/>
<template #overlay> <template #overlay>
<div <div class="sub-menu-overlay" @mouseenter="handleSubMenuMouseEnter" @mouseleave="handleSubMenuMouseLeave">
class="sub-menu-overlay"
@mouseenter="handleSubMenuMouseEnter"
@mouseleave="handleSubMenuMouseLeave"
>
<div class="sub-menu-header"> <div class="sub-menu-header">
<div class="sub-menu-title">{{ selectedLocation.name }} - 操作</div> <div class="sub-menu-title">{{ selectedLocation.name }} - 操作</div>
</div> </div>
@ -131,7 +123,7 @@ const subMenuTriggerRef = ref<HTMLElement | null>(null);
// //
watch(showSubMenu, (newValue) => { watch(showSubMenu, (newValue) => {
if (newValue) { if (newValue) {
selectedLocation.value = props.storageLocations.find(loc => loc.id === newValue) || null; selectedLocation.value = props.storageLocations.find((loc) => loc.id === newValue) || null;
// //
if (hideTimer.value) { if (hideTimer.value) {
clearTimeout(hideTimer.value); clearTimeout(hideTimer.value);
@ -176,13 +168,13 @@ const handleSubMenuMouseLeave = () => {
// - // -
const subMenuTriggerStyle = computed(() => { const subMenuTriggerStyle = computed(() => {
if (!showSubMenu.value) return {}; if (!showSubMenu.value) return {};
// //
const menuItemHeight = 60; // const menuItemHeight = 60; //
const headerHeight = 40; // const headerHeight = 40; //
const itemIndex = props.storageLocations.findIndex(loc => loc.id === showSubMenu.value); const itemIndex = props.storageLocations.findIndex((loc) => loc.id === showSubMenu.value);
const offsetY = headerHeight + (itemIndex * menuItemHeight); const offsetY = headerHeight + itemIndex * menuItemHeight;
const style = { const style = {
position: 'absolute' as const, position: 'absolute' as const,
left: '100%', // left: '100%', //
@ -197,7 +189,6 @@ const subMenuTriggerStyle = computed(() => {
return style; return style;
}); });
// //
const getSubMenuContainer = () => document.body; const getSubMenuContainer = () => document.body;
@ -216,7 +207,6 @@ const hideSubMenu = () => {
} }
}; };
// //
const handleSubMenuOpenChange = (open: boolean) => { const handleSubMenuOpenChange = (open: boolean) => {
if (!open) { if (!open) {
@ -238,11 +228,11 @@ const handleSubMenuOpenChange = (open: boolean) => {
// //
const handleStorageAction = async (action: string, actionName: string) => { const handleStorageAction = async (action: string, actionName: string) => {
if (!selectedLocation.value) return; if (!selectedLocation.value) return;
try { try {
// API // API
const { StorageActionService } = await import('../../services/storageActionService'); const { StorageActionService } = await import('../../services/storageActionService');
// API // API
const apiLocation = { const apiLocation = {
id: selectedLocation.value.id, id: selectedLocation.value.id,
@ -252,25 +242,25 @@ const handleStorageAction = async (action: string, actionName: string) => {
isDisabled: selectedLocation.value.isDisabled, isDisabled: selectedLocation.value.isDisabled,
isEmptyTray: selectedLocation.value.isEmptyTray, isEmptyTray: selectedLocation.value.isEmptyTray,
status: selectedLocation.value.status, status: selectedLocation.value.status,
layer_name: selectedLocation.value.name layer_name: selectedLocation.value.name,
}; };
await StorageActionService.handleStorageAction(action, apiLocation, actionName); await StorageActionService.handleStorageAction(action, apiLocation, actionName);
// //
emit('actionComplete', { emit('actionComplete', {
action, action,
location: selectedLocation.value, location: selectedLocation.value,
success: true success: true,
}); });
} catch (error) { } catch (error) {
console.error(`库位${actionName}操作失败:`, error); console.error(`库位${actionName}操作失败:`, error);
// //
emit('actionComplete', { emit('actionComplete', {
action, action,
location: selectedLocation.value, location: selectedLocation.value,
success: false success: false,
}); });
} }
}; };
@ -350,21 +340,44 @@ const getStorageTooltip = (location: StorageLocationInfo) => {
background-color: #d9d9d9; background-color: #d9d9d9;
} }
.status-indicator.occupied.active { background-color: #ff4d4f; } .status-indicator.occupied.active {
.status-indicator.locked.active { background-color: #faad14; } background-color: #ff4d4f;
.status-indicator.disabled.active { background-color: #8c8c8c; } }
.status-indicator.empty-tray.active { background-color: #13c2c2; } .status-indicator.locked.active {
background-color: #faad14;
}
.status-indicator.disabled.active {
background-color: #8c8c8c;
}
.status-indicator.empty-tray.active {
background-color: #13c2c2;
}
.status-text { .status-text {
color: #666; color: #666;
font-size: 11px; font-size: 11px;
} }
.storage-occupied { background-color: #fff2f0; border-left-color: #ff4d4f; } .storage-occupied {
.storage-locked { background-color: #fffbe6; border-left-color: #faad14; } background-color: #fff2f0;
.storage-disabled { background-color: #f5f5f5; border-left-color: #8c8c8c; } border-left-color: #ff4d4f;
.storage-empty-tray { background-color: #e6fffb; border-left-color: #13c2c2; } }
.storage-available { background-color: #f6ffed; border-left-color: #52c41a; } .storage-locked {
background-color: #fffbe6;
border-left-color: #faad14;
}
.storage-disabled {
background-color: #f5f5f5;
border-left-color: #8c8c8c;
}
.storage-empty-tray {
background-color: #e6fffb;
border-left-color: #13c2c2;
}
.storage-available {
background-color: #f6ffed;
border-left-color: #52c41a;
}
.arrow-icon { .arrow-icon {
color: #999; color: #999;