refactor: 调整存储菜单组件的子菜单位置为右上角,简化代码结构,提升可读性
This commit is contained in:
parent
6c7fcb9eba
commit
6de409bc69
@ -40,21 +40,13 @@
|
||||
v-if="showSubMenu && selectedLocation"
|
||||
:open="!!showSubMenu"
|
||||
:trigger="[]"
|
||||
placement="topRight"
|
||||
placement="rightTop"
|
||||
:get-popup-container="getSubMenuContainer"
|
||||
@open-change="handleSubMenuOpenChange"
|
||||
>
|
||||
<div
|
||||
ref="subMenuTriggerRef"
|
||||
class="sub-menu-trigger"
|
||||
:style="subMenuTriggerStyle"
|
||||
/>
|
||||
<div ref="subMenuTriggerRef" class="sub-menu-trigger" :style="subMenuTriggerStyle" />
|
||||
<template #overlay>
|
||||
<div
|
||||
class="sub-menu-overlay"
|
||||
@mouseenter="handleSubMenuMouseEnter"
|
||||
@mouseleave="handleSubMenuMouseLeave"
|
||||
>
|
||||
<div class="sub-menu-overlay" @mouseenter="handleSubMenuMouseEnter" @mouseleave="handleSubMenuMouseLeave">
|
||||
<div class="sub-menu-header">
|
||||
<div class="sub-menu-title">{{ selectedLocation.name }} - 操作</div>
|
||||
</div>
|
||||
@ -131,7 +123,7 @@ const subMenuTriggerRef = ref<HTMLElement | null>(null);
|
||||
// 监听子菜单显示状态
|
||||
watch(showSubMenu, (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) {
|
||||
clearTimeout(hideTimer.value);
|
||||
@ -176,13 +168,13 @@ const handleSubMenuMouseLeave = () => {
|
||||
// 子菜单触发器样式 - 创建不可见的定位点
|
||||
const subMenuTriggerStyle = computed(() => {
|
||||
if (!showSubMenu.value) return {};
|
||||
|
||||
|
||||
// 计算子菜单触发器的位置,让子菜单的左上角与父菜单的右上角平齐
|
||||
const menuItemHeight = 60; // 库位项的高度
|
||||
const headerHeight = 40; // 菜单头部高度
|
||||
const itemIndex = props.storageLocations.findIndex(loc => loc.id === showSubMenu.value);
|
||||
const offsetY = headerHeight + (itemIndex * menuItemHeight);
|
||||
|
||||
const itemIndex = props.storageLocations.findIndex((loc) => loc.id === showSubMenu.value);
|
||||
const offsetY = headerHeight + itemIndex * menuItemHeight;
|
||||
|
||||
const style = {
|
||||
position: 'absolute' as const,
|
||||
left: '100%', // 紧贴主菜单右侧
|
||||
@ -197,7 +189,6 @@ const subMenuTriggerStyle = computed(() => {
|
||||
return style;
|
||||
});
|
||||
|
||||
|
||||
// 获取子菜单弹出层容器
|
||||
const getSubMenuContainer = () => document.body;
|
||||
|
||||
@ -216,7 +207,6 @@ const hideSubMenu = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 处理子菜单开关变化
|
||||
const handleSubMenuOpenChange = (open: boolean) => {
|
||||
if (!open) {
|
||||
@ -238,11 +228,11 @@ const handleSubMenuOpenChange = (open: boolean) => {
|
||||
// 库位操作处理
|
||||
const handleStorageAction = async (action: string, actionName: string) => {
|
||||
if (!selectedLocation.value) return;
|
||||
|
||||
|
||||
try {
|
||||
// 直接调用API,不需要勾选
|
||||
const { StorageActionService } = await import('../../services/storageActionService');
|
||||
|
||||
|
||||
// 转换类型以匹配API期望的格式
|
||||
const apiLocation = {
|
||||
id: selectedLocation.value.id,
|
||||
@ -252,25 +242,25 @@ const handleStorageAction = async (action: string, actionName: string) => {
|
||||
isDisabled: selectedLocation.value.isDisabled,
|
||||
isEmptyTray: selectedLocation.value.isEmptyTray,
|
||||
status: selectedLocation.value.status,
|
||||
layer_name: selectedLocation.value.name
|
||||
layer_name: selectedLocation.value.name,
|
||||
};
|
||||
|
||||
|
||||
await StorageActionService.handleStorageAction(action, apiLocation, actionName);
|
||||
|
||||
|
||||
// 发送操作完成事件
|
||||
emit('actionComplete', {
|
||||
action,
|
||||
location: selectedLocation.value,
|
||||
success: true
|
||||
success: true,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`库位${actionName}操作失败:`, error);
|
||||
|
||||
|
||||
// 发送操作失败事件
|
||||
emit('actionComplete', {
|
||||
action,
|
||||
location: selectedLocation.value,
|
||||
success: false
|
||||
success: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -350,21 +340,44 @@ const getStorageTooltip = (location: StorageLocationInfo) => {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.status-indicator.occupied.active { background-color: #ff4d4f; }
|
||||
.status-indicator.locked.active { background-color: #faad14; }
|
||||
.status-indicator.disabled.active { background-color: #8c8c8c; }
|
||||
.status-indicator.empty-tray.active { background-color: #13c2c2; }
|
||||
.status-indicator.occupied.active {
|
||||
background-color: #ff4d4f;
|
||||
}
|
||||
.status-indicator.locked.active {
|
||||
background-color: #faad14;
|
||||
}
|
||||
.status-indicator.disabled.active {
|
||||
background-color: #8c8c8c;
|
||||
}
|
||||
.status-indicator.empty-tray.active {
|
||||
background-color: #13c2c2;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
color: #666;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.storage-occupied { background-color: #fff2f0; border-left-color: #ff4d4f; }
|
||||
.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; }
|
||||
.storage-occupied {
|
||||
background-color: #fff2f0;
|
||||
border-left-color: #ff4d4f;
|
||||
}
|
||||
.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 {
|
||||
color: #999;
|
||||
|
Loading…
x
Reference in New Issue
Block a user