From de18a5db43131dde1ec8b7ac9327f1802f2120a9 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期二, 10 三月 2026 09:03:21 +0800
Subject: [PATCH] 批次出库过滤忽略
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java | 7
rsf-open-api/src/main/java/com/vincent/rsf/openApi/config/ApiSecurityConfig.java | 2
rsf-admin/src/layout/TabsBar.jsx | 380 ++++++++++++++++++++++++++---------------------------
3 files changed, 190 insertions(+), 199 deletions(-)
diff --git a/rsf-admin/src/layout/TabsBar.jsx b/rsf-admin/src/layout/TabsBar.jsx
index b4641ae..14ed18e 100644
--- a/rsf-admin/src/layout/TabsBar.jsx
+++ b/rsf-admin/src/layout/TabsBar.jsx
@@ -7,32 +7,27 @@
import SettingsIcon from '@mui/icons-material/Settings';
import ClearAllIcon from '@mui/icons-material/ClearAll';
-// 鍥哄畾鐨勬爣绛鹃〉閰嶇疆 (涓嶅彲鍏抽棴)
+// 鍥哄畾鏍囩椤甸厤缃紙涓嶅彲鍏抽棴锛�
const FIXED_TABS = [
{ path: '/dashboard', name: 'menu.dashboard', closable: false }
];
-// 鐗规畩椤甸潰閰嶇疆
const SPECIAL_PAGES = {
'/settings': { name: 'menu.settings', closable: true },
'/dashboard': { name: 'menu.dashboard', closable: false }
};
-// 蹇界暐鐨勮矾寰勬ā寮� (鐧诲綍椤点�佹牴璺緞绛�)
const IGNORED_PATHS = ['/', '/login'];
-// 浠巐ocalStorage鑾峰彇宸蹭繚瀛樼殑鏍囩椤�
const getSavedTabs = () => {
try {
const saved = localStorage.getItem('openTabs');
if (saved) {
const parsed = JSON.parse(saved);
- // 纭繚 dashboard 濮嬬粓瀛樺湪涓旀槸绗竴涓�
const hasDashboard = parsed.some(tab => tab.path === '/dashboard');
if (!hasDashboard) {
return [...FIXED_TABS, ...parsed.filter(tab => tab.path !== '/dashboard')];
}
- // 纭繚 dashboard 鍦ㄧ涓�浣�
const dashboard = parsed.find(tab => tab.path === '/dashboard');
const others = parsed.filter(tab => tab.path !== '/dashboard');
return [{ ...dashboard, closable: false }, ...others];
@@ -43,7 +38,6 @@
}
};
-// 淇濆瓨鏍囩椤靛埌localStorage
const saveTabs = (tabs) => {
try {
localStorage.setItem('openTabs', JSON.stringify(tabs));
@@ -52,32 +46,25 @@
}
};
-// 瑙勮寖鍖栬矾寰� - 澶勭悊甯D鐨勮鎯�/缂栬緫椤甸潰
const normalizePath = (path) => {
if (!path) return path;
-
- // 鍖归厤妯″紡: /resource/123/show 鎴� /resource/123/edit 鎴� /resource/123
- // 灏嗗叾瑙勮寖鍖栦负鍩虹璺緞 /resource
const patterns = [
- /^(\/[^/]+)\/\d+\/(show|edit)$/, // /task/123/show -> /task
- /^(\/[^/]+)\/\d+$/, // /task/123 -> /task
- /^(\/[^/]+)\/create$/, // /task/create -> /task
+ /^(\/[^/]+)\/\d+\/(show|edit)$/,
+ /^(\/[^/]+)\/\d+$/,
+ /^(\/[^/]+)\/create$/,
];
-
for (const pattern of patterns) {
const match = path.match(pattern);
- if (match) {
- return match[1];
- }
+ if (match) return match[1];
}
-
return path;
};
-// 鍒ゆ柇涓や釜璺緞鏄惁灞炰簬鍚屼竴璧勬簮
const isSameResource = (path1, path2) => {
return normalizePath(path1) === normalizePath(path2);
};
+
+const LONG_PRESS_MS = 300;
const TabsBar = () => {
const location = useLocation();
@@ -86,16 +73,42 @@
const { permissions } = usePermissions();
const [tabs, setTabs] = useState(getSavedTabs);
const pendingNavigationRef = useRef(null);
+ const tabsBarRef = useRef(null);
const [contextMenu, setContextMenu] = useState(null);
const [contextMenuTab, setContextMenuTab] = useState(null);
+ const contextMenuOpenRef = useRef(false);
+ contextMenuOpenRef.current = contextMenu !== null;
- // 缈昏瘧杈呭姪鍑芥暟锛屽鏋滅炕璇戜笉瀛樺湪鍒欒繑鍥為粯璁ゅ��
+ const [draggingIndex, setDraggingIndex] = useState(null);
+ const [dropIndicatorIndex, setDropIndicatorIndex] = useState(null);
+ const longPressTimerRef = useRef(null);
+ const longPressIndexRef = useRef(null);
+ const justFinishedDragRef = useRef(false);
+
+ // 鍦ㄦ爣绛鹃〉鍙抽敭鏃堕樆姝㈡祻瑙堝櫒榛樿鑿滃崟
+ useEffect(() => {
+ const onDocContextMenu = (e) => {
+ const inTabsBarByTarget = tabsBarRef.current && tabsBarRef.current.contains(e.target);
+ let inTabsBarByPos = false;
+ if (tabsBarRef.current) {
+ const rect = tabsBarRef.current.getBoundingClientRect();
+ inTabsBarByPos = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
+ }
+ const inTabsBar = inTabsBarByTarget || inTabsBarByPos;
+ const menuOpen = contextMenuOpenRef.current;
+ if (inTabsBar || menuOpen) {
+ e.preventDefault();
+ }
+ };
+ document.addEventListener('contextmenu', onDocContextMenu, true);
+ return () => document.removeEventListener('contextmenu', onDocContextMenu, true);
+ }, []);
+
const t = useCallback((key, defaultValue) => {
const translated = translate(key);
return translated === key ? defaultValue : translated;
}, [translate]);
- // 澶勭悊寰呮墽琛岀殑瀵艰埅
useEffect(() => {
if (pendingNavigationRef.current) {
navigate(pendingNavigationRef.current);
@@ -103,7 +116,6 @@
}
});
- // 鏍规嵁璺緞鏌ユ壘鑿滃崟鍚嶇О
const findMenuName = useCallback((path, menus) => {
if (!menus || !path) return null;
const cleanPath = path.replace(/^\//, '');
@@ -124,51 +136,30 @@
return searchMenu(menus);
}, []);
- // 鑾峰彇鏍囩椤垫樉绀哄悕绉�
const getTabLabel = useCallback((tab) => {
- // 鍥哄畾鏍囩椤电洿鎺ヨ繑鍥炵炕璇戝悗鐨勫悕绉�
- if (tab.name) {
- return translate(tab.name);
- }
-
- // 妫�鏌ョ壒娈婇〉闈�
+ if (tab.name) return translate(tab.name);
const normalizedPath = normalizePath(tab.path);
if (SPECIAL_PAGES[normalizedPath]) {
return translate(SPECIAL_PAGES[normalizedPath].name);
}
-
- // 鍔ㄦ�佹爣绛鹃〉灏濊瘯浠庢潈闄愪腑鑾峰彇鍚嶇О
if (permissions) {
const menuName = findMenuName(tab.path, permissions);
- if (menuName) {
- return translate(menuName);
- }
+ if (menuName) return translate(menuName);
}
- // 榛樿杩斿洖璺緞
return tab.path.replace(/^\//, '').split('/')[0] || tab.path;
}, [translate, permissions, findMenuName]);
- // 鐩戝惉璺敱鍙樺寲锛屾坊鍔犳柊鏍囩椤�
useEffect(() => {
const currentPath = location.pathname;
-
- // 蹇界暐鐗瑰畾璺緞
- if (IGNORED_PATHS.includes(currentPath)) {
- return;
- }
+ if (IGNORED_PATHS.includes(currentPath)) return;
setTabs(prevTabs => {
- // 妫�鏌ユ槸鍚﹀凡鏈夌浉鍚岃祫婧愮殑鏍囩椤�
const existingTabIndex = prevTabs.findIndex(tab =>
tab.path === currentPath || isSameResource(tab.path, currentPath)
);
if (existingTabIndex >= 0) {
- // 濡傛灉璺緞瀹屽叏鐩稿悓锛屼笉闇�瑕佹洿鏂�
- if (prevTabs[existingTabIndex].path === currentPath) {
- return prevTabs;
- }
- // 鏇存柊鐜版湁鏍囩椤电殑璺緞锛堜繚鎸佹爣绛句綅缃級
+ if (prevTabs[existingTabIndex].path === currentPath) return prevTabs;
const updatedTabs = [...prevTabs];
updatedTabs[existingTabIndex] = {
...updatedTabs[existingTabIndex],
@@ -178,19 +169,13 @@
return updatedTabs;
}
- // 鏌ユ壘鑿滃崟鍚嶇О
let menuName = null;
- if (permissions) {
- menuName = findMenuName(currentPath, permissions);
- }
-
- // 妫�鏌ョ壒娈婇〉闈�
+ if (permissions) menuName = findMenuName(currentPath, permissions);
const normalizedPath = normalizePath(currentPath);
if (SPECIAL_PAGES[normalizedPath] && !menuName) {
menuName = SPECIAL_PAGES[normalizedPath].name;
}
- // 娣诲姞鏂版爣绛鹃〉
const newTab = {
path: currentPath,
name: menuName,
@@ -202,15 +187,17 @@
});
}, [location.pathname, permissions, findMenuName]);
- // 鍒囨崲鏍囩椤�
const handleTabChange = (event, newValue) => {
+ if (justFinishedDragRef.current) {
+ justFinishedDragRef.current = false;
+ return;
+ }
const targetTab = tabs[newValue];
if (targetTab && targetTab.path !== location.pathname) {
navigate(targetTab.path);
}
};
- // 鍏抽棴鏍囩椤�
const handleCloseTab = (event, tabPath) => {
event.stopPropagation();
event.preventDefault();
@@ -218,9 +205,7 @@
const tabIndex = tabs.findIndex(tab => tab.path === tabPath);
const newTabs = tabs.filter(tab => tab.path !== tabPath);
- // 濡傛灉鍏抽棴鐨勬槸褰撳墠鏍囩椤碉紝闇�瑕佸鑸埌鍏朵粬鏍囩椤�
if (location.pathname === tabPath || isSameResource(location.pathname, tabPath)) {
- // 浼樺厛瀵艰埅鍒板乏杈圭殑鏍囩椤碉紝鍚﹀垯瀵艰埅鍒板彸杈圭殑
const newIndex = Math.min(tabIndex, newTabs.length - 1);
if (newIndex >= 0 && newTabs[newIndex]) {
pendingNavigationRef.current = newTabs[newIndex].path;
@@ -233,59 +218,37 @@
setTabs(newTabs);
};
-
-
- // 鍏抽棴鎵�鏈夋爣绛鹃〉锛堥櫎浜哾ashboard锛�
const handleCloseAll = () => {
const dashboardTab = tabs.find(tab => tab.path === '/dashboard');
const newTabs = [dashboardTab || { ...FIXED_TABS[0] }];
-
saveTabs(newTabs);
setTabs(newTabs);
-
if (location.pathname !== '/dashboard') {
navigate('/dashboard');
}
};
- // 鍏抽棴鍏朵粬鏍囩椤碉紙淇濈暀鎸囧畾鏍囩椤碉級
const handleCloseOthers = (keepTabPath) => {
const keepTab = tabs.find(tab => tab.path === keepTabPath);
- if (!keepTab) {
- return;
- }
-
- // 淇濈暀鎸囧畾鏍囩椤靛拰dashboard锛堝鏋渄ashboard涓嶆槸鎸囧畾鏍囩椤碉級
+ if (!keepTab) return;
const dashboardTab = tabs.find(tab => tab.path === '/dashboard');
const newTabs = [];
-
- // 濡傛灉鎸囧畾鏍囩椤典笉鏄痙ashboard锛岀‘淇漝ashboard涔熷湪鍒楄〃涓�
if (keepTab.path !== '/dashboard' && dashboardTab) {
newTabs.push(dashboardTab);
}
-
- // 娣诲姞鎸囧畾鏍囩椤碉紙濡傛灉杩樻病鏈夋坊鍔狅級
if (!newTabs.some(tab => tab.path === keepTab.path)) {
newTabs.push(keepTab);
}
-
saveTabs(newTabs);
setTabs(newTabs);
setContextMenu(null);
setContextMenuTab(null);
};
- //鍏抽棴宸︿晶鏍囩椤碉紙淇濈暀鎸囧畾鏍囩椤靛強鍏跺彸渚х殑鎵�鏈夋爣绛鹃〉锛�
const handleCloseLeft = (keepTabPath) => {
const keepTabIndex = tabs.findIndex(tab => tab.path === keepTabPath);
- if (keepTabIndex < 0) {
- return;
- }
-
- // 淇濈暀鎸囧畾鏍囩椤靛強鍏跺彸渚х殑鎵�鏈夋爣绛鹃〉
- const newTabs = tabs.slice(keepTabIndex);
-
- // 纭繚dashboard濮嬬粓鍦ㄧ涓�浣嶏紙濡傛灉瀛樺湪锛�
+ if (keepTabIndex < 0) return;
+ let newTabs = tabs.slice(keepTabIndex);
const dashboardTab = newTabs.find(tab => tab.path === '/dashboard');
if (dashboardTab && newTabs[0].path !== '/dashboard') {
const dashboardIndex = newTabs.findIndex(tab => tab.path === '/dashboard');
@@ -294,30 +257,22 @@
newTabs.unshift(dashboardTab);
}
}
-
saveTabs(newTabs);
setTabs(newTabs);
setContextMenu(null);
setContextMenuTab(null);
};
- // 鍏抽棴鍙充晶鏍囩椤碉紙淇濈暀鎸囧畾鏍囩椤靛強鍏跺乏渚х殑鎵�鏈夋爣绛鹃〉锛�
const handleCloseRight = (keepTabPath) => {
const keepTabIndex = tabs.findIndex(tab => tab.path === keepTabPath);
- if (keepTabIndex < 0) {
- return;
- }
-
- // 淇濈暀鎸囧畾鏍囩椤靛強鍏跺乏渚х殑鎵�鏈夋爣绛鹃〉
+ if (keepTabIndex < 0) return;
const newTabs = tabs.slice(0, keepTabIndex + 1);
-
saveTabs(newTabs);
setTabs(newTabs);
setContextMenu(null);
setContextMenuTab(null);
};
- // 澶勭悊鍙抽敭鑿滃崟
const handleContextMenu = (event, tab) => {
event.preventDefault();
event.stopPropagation();
@@ -329,33 +284,24 @@
canCloseRightForTab(tab.path) ||
canCloseOthersForTab(tab.path);
if (!hasItems) return;
- setContextMenu({
- mouseX: event.clientX + 2,
- mouseY: event.clientY - 6,
- });
+ setContextMenu({ mouseX: event.clientX + 2, mouseY: event.clientY - 6 });
setContextMenuTab(tab);
};
- // 鍏抽棴鍙抽敭鑿滃崟
const handleCloseContextMenu = () => {
setContextMenu(null);
setContextMenuTab(null);
};
- // 鍙抽敭鑿滃崟锛氬叧闂綋鍓嶆爣绛�
const handleCloseCurrentTab = () => {
if (!contextMenuTab) {
handleCloseContextMenu();
return;
}
-
const tabPath = contextMenuTab.path;
const tabIndex = tabs.findIndex(tab => tab.path === tabPath);
const newTabs = tabs.filter(tab => tab.path !== tabPath);
-
- // 濡傛灉鍏抽棴鐨勬槸褰撳墠鏍囩椤碉紝闇�瑕佸鑸埌鍏朵粬鏍囩椤�
if (location.pathname === tabPath || isSameResource(location.pathname, tabPath)) {
- // 浼樺厛瀵艰埅鍒板乏杈圭殑鏍囩椤碉紝鍚﹀垯瀵艰埅鍒板彸杈圭殑
const newIndex = Math.min(tabIndex, newTabs.length - 1);
if (newIndex >= 0 && newTabs[newIndex]) {
pendingNavigationRef.current = newTabs[newIndex].path;
@@ -363,73 +309,148 @@
pendingNavigationRef.current = '/dashboard';
}
}
-
saveTabs(newTabs);
setTabs(newTabs);
handleCloseContextMenu();
};
- // 鍙抽敭鑿滃崟锛氬叧闂叾浠栨爣绛�
const handleCloseOtherTabs = () => {
- if (contextMenuTab) {
- handleCloseOthers(contextMenuTab.path);
- }
+ if (contextMenuTab) handleCloseOthers(contextMenuTab.path);
};
-
- // 鍙抽敭鑿滃崟锛氬叧闂乏渚ф爣绛�
const handleCloseLeftTabs = () => {
- if (contextMenuTab) {
- handleCloseLeft(contextMenuTab.path);
- }
+ if (contextMenuTab) handleCloseLeft(contextMenuTab.path);
};
-
- // 鍙抽敭鑿滃崟锛氬叧闂彸渚ф爣绛�
const handleCloseRightTabs = () => {
- if (contextMenuTab) {
- handleCloseRight(contextMenuTab.path);
- }
+ if (contextMenuTab) handleCloseRight(contextMenuTab.path);
};
+ const canCloseOthersForTab = (tabPath) => {
+ return tabs.filter(tab => {
+ const isTarget = tab.path === tabPath || isSameResource(tab.path, tabPath);
+ return !isTarget && tab.closable;
+ }).length > 0;
+ };
+ const canCloseLeftForTab = (tabPath) => {
+ const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath));
+ if (tabIndex <= 0) return false;
+ return tabs.slice(0, tabIndex).some(tab => tab.closable);
+ };
+ const canCloseRightForTab = (tabPath) => {
+ const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath));
+ if (tabIndex < 0 || tabIndex >= tabs.length - 1) return false;
+ return tabs.slice(tabIndex + 1).some(tab => tab.closable);
+ };
- // 鑾峰彇褰撳墠鏍囩椤电储寮�
const currentTabIndex = tabs.findIndex(tab =>
tab.path === location.pathname || isSameResource(tab.path, location.pathname)
);
const activeIndex = currentTabIndex >= 0 ? currentTabIndex : 0;
-
- // 鍒ゆ柇鏄惁鏈夊彲鍏抽棴鐨勬爣绛�
const hasClosableTabs = tabs.some(tab => tab.closable);
- // 鍒ゆ柇鎸囧畾鏍囩椤垫槸鍚﹀彲浠ュ叧闂叾浠栨爣绛�
- const canCloseOthersForTab = (tabPath) => {
- return tabs.filter(tab => {
- const isTargetTab = tab.path === tabPath || isSameResource(tab.path, tabPath);
- return !isTargetTab && tab.closable;
- }).length > 0;
- };
+ // 鍙抽敭鎵撳紑鏃讹紝鐐瑰嚮鑿滃崟鍜屾爣绛炬爮澶栧叧闂�
+ const menuPaperRef = useRef(null);
+ useEffect(() => {
+ if (contextMenu === null) return;
+ const onDocClick = (e) => {
+ const inMenu = menuPaperRef.current && menuPaperRef.current.contains(e.target);
+ const inTabsBar = tabsBarRef.current && tabsBarRef.current.contains(e.target);
+ if (!inMenu && !inTabsBar) {
+ setContextMenu(null);
+ setContextMenuTab(null);
+ }
+ };
+ document.addEventListener('mousedown', onDocClick, true);
+ return () => document.removeEventListener('mousedown', onDocClick, true);
+ }, [contextMenu]);
- // 鍒ゆ柇鎸囧畾鏍囩椤垫槸鍚﹀彲浠ュ叧闂乏渚ф爣绛�
- const canCloseLeftForTab = (tabPath) => {
- const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath));
- if (tabIndex <= 0) {
- return false; // 娌℃湁宸︿晶鏍囩鎴栬繖鏄涓�涓爣绛�
+ const clearLongPressTimer = useCallback(() => {
+ if (longPressTimerRef.current) {
+ clearTimeout(longPressTimerRef.current);
+ longPressTimerRef.current = null;
}
- // 妫�鏌ュ乏渚ф槸鍚︽湁鍙叧闂殑鏍囩锛堟帓闄ashboard锛�
- return tabs.slice(0, tabIndex).some(tab => tab.closable);
- };
+ longPressIndexRef.current = null;
+ }, []);
- // 鍒ゆ柇鎸囧畾鏍囩椤垫槸鍚﹀彲浠ュ叧闂彸渚ф爣绛�
- const canCloseRightForTab = (tabPath) => {
- const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath));
- if (tabIndex < 0 || tabIndex >= tabs.length - 1) {
- return false; // 娌℃湁鍙充晶鏍囩鎴栬繖鏄渶鍚庝竴涓爣绛�
- }
- // 妫�鏌ュ彸渚ф槸鍚︽湁鍙叧闂殑鏍囩
- return tabs.slice(tabIndex + 1).some(tab => tab.closable);
- };
+ const handleTabPointerDown = useCallback((e, index) => {
+ if (index < 0) return;
+ longPressIndexRef.current = index;
+ longPressTimerRef.current = setTimeout(() => {
+ longPressTimerRef.current = null;
+ setDraggingIndex(index);
+ setDropIndicatorIndex(index);
+ }, LONG_PRESS_MS);
+ }, []);
+
+ const handleTabPointerUp = useCallback(() => {
+ clearLongPressTimer();
+ }, [clearLongPressTimer]);
+
+ useEffect(() => {
+ if (draggingIndex === null) return;
+ const getDropIndex = (clientX) => {
+ const nodes = tabsBarRef.current?.querySelectorAll('[data-tab-index]');
+ if (!nodes?.length) return draggingIndex;
+ for (let i = 0; i < nodes.length; i++) {
+ const rect = nodes[i].getBoundingClientRect();
+ const mid = rect.left + rect.width / 2;
+ if (clientX <= mid) {
+ const drop = i;
+ if (draggingIndex === 0) return drop <= 0 ? 0 : draggingIndex;
+ return drop <= 0 ? 1 : drop;
+ }
+ }
+ const drop = nodes.length;
+ return draggingIndex === 0 ? 0 : drop;
+ };
+ const clientXFromEvent = (e) => e.clientX ?? e.touches?.[0]?.clientX;
+ const onMove = (e) => {
+ const x = clientXFromEvent(e);
+ if (x != null) setDropIndicatorIndex(getDropIndex(x));
+ };
+ const onTouchMove = (e) => {
+ e.preventDefault();
+ onMove(e);
+ };
+ const onUp = () => {
+ justFinishedDragRef.current = true;
+ setDraggingIndex((di) => {
+ setDropIndicatorIndex((dropIdx) => {
+ if (di !== null && dropIdx !== null && di !== dropIdx) {
+ const newTabs = [...tabs];
+ const [item] = newTabs.splice(di, 1);
+ const insertAt = dropIdx > di ? dropIdx - 1 : dropIdx;
+ newTabs.splice(insertAt, 0, item);
+ const dashboard = newTabs.find((t) => t.path === '/dashboard');
+ if (dashboard && newTabs[0].path !== '/dashboard') {
+ const idx = newTabs.indexOf(dashboard);
+ newTabs.splice(idx, 1);
+ newTabs.unshift(dashboard);
+ }
+ saveTabs(newTabs);
+ setTabs(newTabs);
+ }
+ return null;
+ });
+ return null;
+ });
+ };
+ document.addEventListener('mousemove', onMove, true);
+ document.addEventListener('mouseup', onUp, true);
+ document.addEventListener('touchmove', onTouchMove, { passive: false, capture: true });
+ document.addEventListener('touchend', onUp, true);
+ document.addEventListener('touchcancel', onUp, true);
+ return () => {
+ document.removeEventListener('mousemove', onMove, true);
+ document.removeEventListener('mouseup', onUp, true);
+ document.removeEventListener('touchmove', onTouchMove, true);
+ document.removeEventListener('touchend', onUp, true);
+ document.removeEventListener('touchcancel', onUp, true);
+ };
+ }, [draggingIndex, tabs]);
return (
<Box
+ ref={tabsBarRef}
sx={{
width: '100%',
backgroundColor: '#fff',
@@ -461,12 +482,20 @@
key={tab.path}
label={
<Box
+ data-tab-index={index}
onContextMenu={(e) => handleContextMenu(e, tab)}
+ onMouseDown={(e) => handleTabPointerDown(e, index)}
+ onMouseUp={handleTabPointerUp}
+ onMouseLeave={handleTabPointerUp}
+ onTouchStart={(e) => handleTabPointerDown(e, index)}
+ onTouchEnd={handleTabPointerUp}
+ onTouchCancel={handleTabPointerUp}
sx={{
display: 'flex',
alignItems: 'center',
gap: 0.5,
width: '100%',
+ ...(draggingIndex === index && { opacity: 0.7 }),
}}
>
{tab.path === '/dashboard' && (
@@ -485,18 +514,16 @@
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
- p: 0.35,
+ p: 0.25,
ml: 0.5,
borderRadius: '50%',
cursor: 'pointer',
- color: 'inherit',
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
- color: '#d32f2f',
},
}}
>
- <CloseIcon sx={{ fontSize: 16 }} />
+ <CloseIcon sx={{ fontSize: 14 }} />
</Box>
</Tooltip>
)}
@@ -523,7 +550,6 @@
/>
))}
</Tabs>
- {/* 娓呴櫎鎵�鏈夋爣绛炬寜閽� */}
{hasClosableTabs && (
<Box sx={{ display: 'flex', alignItems: 'center', pr: 1 }}>
<Divider orientation="vertical" flexItem sx={{ mx: 0.5, height: 20, alignSelf: 'center' }} />
@@ -545,7 +571,6 @@
</Tooltip>
</Box>
)}
- {/* 鍙抽敭鑿滃崟 */}
<Menu
open={contextMenu !== null}
onClose={handleCloseContextMenu}
@@ -556,8 +581,12 @@
: undefined
}
disableScrollLock
- ModalProps={{ disablePortal: true }}
+ ModalProps={{
+ disablePortal: true,
+ BackdropProps: { sx: { pointerEvents: 'none' } },
+ }}
PaperProps={{
+ ref: menuPaperRef,
sx: {
minWidth: 120,
borderRadius: '8px',
@@ -566,59 +595,20 @@
py: 0.5,
},
}}
- MenuListProps={{
- sx: { py: 0 },
- }}
+ MenuListProps={{ sx: { py: 0 } }}
>
- {contextMenuTab && contextMenuTab.closable && (
- <MenuItem
- onClick={handleCloseCurrentTab}
- sx={{
- fontSize: '0.8125rem',
- py: 0.75,
- px: 1.5,
- minHeight: 'auto',
- }}
- >
- {t('ra.action.close', '鍏抽棴褰撳墠鏍囩')}
- </MenuItem>
- )}
{contextMenuTab && canCloseLeftForTab(contextMenuTab.path) && (
- <MenuItem
- onClick={handleCloseLeftTabs}
- sx={{
- fontSize: '0.8125rem',
- py: 0.75,
- px: 1.5,
- minHeight: 'auto',
- }}
- >
+ <MenuItem onClick={handleCloseLeftTabs} sx={{ fontSize: '0.8125rem', py: 0.75, px: 1.5, minHeight: 'auto' }}>
{t('ra.action.closeLeft', '鍏抽棴宸︿晶鏍囩')}
</MenuItem>
)}
{contextMenuTab && canCloseRightForTab(contextMenuTab.path) && (
- <MenuItem
- onClick={handleCloseRightTabs}
- sx={{
- fontSize: '0.8125rem',
- py: 0.75,
- px: 1.5,
- minHeight: 'auto',
- }}
- >
+ <MenuItem onClick={handleCloseRightTabs} sx={{ fontSize: '0.8125rem', py: 0.75, px: 1.5, minHeight: 'auto' }}>
{t('ra.action.closeRight', '鍏抽棴鍙充晶鏍囩')}
</MenuItem>
)}
{contextMenuTab && canCloseOthersForTab(contextMenuTab.path) && (
- <MenuItem
- onClick={handleCloseOtherTabs}
- sx={{
- fontSize: '0.8125rem',
- py: 0.75,
- px: 1.5,
- minHeight: 'auto',
- }}
- >
+ <MenuItem onClick={handleCloseOtherTabs} sx={{ fontSize: '0.8125rem', py: 0.75, px: 1.5, minHeight: 'auto' }}>
{t('ra.action.closeOthers', '鍏抽棴鍏朵粬鏍囩')}
</MenuItem>
)}
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/config/ApiSecurityConfig.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/config/ApiSecurityConfig.java
index b2b6c7d..ef6651c 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/config/ApiSecurityConfig.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/config/ApiSecurityConfig.java
@@ -20,7 +20,7 @@
public FilterRegistrationBean<AppIdAuthenticationFilter> apiAuthenticationFilter() {
FilterRegistrationBean<AppIdAuthenticationFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(appIdAuthenticationFilter);
- registrationBean.addUrlPatterns("/api/*", "/erp/*", "/cloudwms/*", "/mes/*", "/agv/*");
+ registrationBean.addUrlPatterns("/api/*"/*, "/erp/*", "/cloudwms/*"*/, "/mes/*", "/agv/*");
registrationBean.setName("apiAuthenticationFilter");
registrationBean.setOrder(1);
return registrationBean;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index cc79c6d..4e97b9b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -943,13 +943,14 @@
if (issued.compareTo(ISSUED_TOLERANCE) <= 0) {
continue;
}
+ // 鍑哄簱鍒嗛厤涓嶆寜鎵规杩囨护锛屼粎鎸夌墿鏂欑紪鐮佹煡搴撲綅锛屼究浜庢甯告娴嬪埌鍙嚭搴撳簱瀛�
List<LocItem> locItems = new ArrayList<>();
if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) {
- locItems = LocManageUtil.getEfficiencyFirstItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme());
+ locItems = LocManageUtil.getEfficiencyFirstItemList(wkOrderItem.getMatnrCode(), null, wkOrderItem.getAnfme());
} else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) {
- locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme());
+ locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), null, wkOrderItem.getAnfme());
} else {
- locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), wkOrderItem.getSplrBatch(), wkOrderItem.getAnfme());
+ locItems = LocManageUtil.getFirstInFirstOutItemList(wkOrderItem.getMatnrCode(), null, wkOrderItem.getAnfme());
}
for (LocItem locItem : locItems) {
Loc loc = locService.getById(locItem.getLocId());
--
Gitblit v1.9.1