From 39154a82354b08c2449918c0665457fdb2701b9b Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期五, 16 十月 2026 16:02:23 +0800
Subject: [PATCH] 设备模块各标签页弹窗新增草稿自动保存与恢复:编辑或录入数据中途关闭/刷新页面,再次打开同一弹窗时自动恢复未保存的编辑内容(弹窗显示"已恢复上次未保存的编辑内容"提示),保存成功后草稿自动清除;新增 src/mixins/draftSave.js 同时清理设备死代码:management.vue 数采配置旧弹窗及其提交方法、calibration.vue 被注释的导出按钮、device.js 中 numberCollect/deviceMetricRecordExport 两个死接口定义
---
src/layout/components/Navbar.vue | 84 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 6db7c89..159b3f1 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -5,6 +5,28 @@
<span class="label">LIMS瀹為獙瀹ょ鐞嗙郴缁�</span>
</div>
<div class="right-menu">
+ <div class="menu-search">
+ <el-select
+ v-model="selectedMenu"
+ placeholder="鎼滅储鑿滃崟"
+ filterable
+ clearable
+ :fit-input-width="false"
+ :filter-method="filterMenus"
+ @change="handleMenuSelect"
+ @clear="resetMenuFilter"
+ >
+ <template #prefix>
+ <lims-icon name="el-icon-search" />
+ </template>
+ <el-option
+ v-for="item in filteredMenus"
+ :key="item.path"
+ :label="item.breadcrumb"
+ :value="item.path"
+ />
+ </el-select>
+ </div>
<div class="avatar-wrapper">
<el-avatar shape="square" :size="30">{{ avatarText }}</el-avatar>
<span class="userName">{{ userStore.nickName }}</span>
@@ -31,11 +53,61 @@
import Hamburger from '@/components/Hamburger'
import useAppStore from '@/store/modules/app'
import useUserStore from '@/store/modules/user'
+import usePermissionStore from '@/store/modules/permission'
+import { getNormalPath } from '@/utils/ruoyi'
const appStore = useAppStore()
const userStore = useUserStore()
+const permissionStore = usePermissionStore()
+const router = useRouter()
const avatarText = computed(() => (userStore.nickName || '').substring(0, 1))
+
+const selectedMenu = ref(undefined)
+const filteredMenus = ref([])
+
+// 渚ц竟鏍忚彍鍗曟爲鎷嶅钩鎴愬彲鎼滅储鍒楄〃锛堟爣棰� + 瀹屾暣璺緞闈㈠寘灞戯級
+const menuList = computed(() => {
+ const list = []
+ const walk = (routes, basePath, parents) => {
+ ;(routes || []).forEach(route => {
+ if (!route || route.hidden || typeof route.path !== 'string') return
+ const fullPath = getNormalPath(`${basePath}/${route.path}`)
+ const title = route.meta && route.meta.title
+ const children = Array.isArray(route.children) ? route.children : []
+ if (children.length) {
+ walk(children, fullPath, title ? parents.concat(title) : parents)
+ } else if (title && fullPath) {
+ list.push({ title, path: fullPath, breadcrumb: parents.concat(title).join(' / ') })
+ }
+ })
+ }
+ walk(permissionStore.sidebarRouters, '', [])
+ return list
+})
+
+function filterMenus(query) {
+ const q = (query || '').trim().toLowerCase()
+ filteredMenus.value = q
+ ? menuList.value.filter(item =>
+ item.title.toLowerCase().includes(q) || item.breadcrumb.toLowerCase().includes(q)
+ )
+ : menuList.value
+}
+
+function resetMenuFilter() {
+ filteredMenus.value = menuList.value
+}
+
+function handleMenuSelect(path) {
+ if (path) {
+ router.push(path).catch(() => {})
+ }
+ selectedMenu.value = undefined
+ resetMenuFilter()
+}
+
+watch(menuList, resetMenuFilter, { immediate: true })
function toggleSideBar() {
appStore.toggleSideBar()
@@ -123,6 +195,18 @@
outline: none;
}
+ .menu-search {
+ margin-right: 20px;
+
+ :deep(.el-select) {
+ width: 210px;
+ }
+
+ :deep(.el-select__wrapper) {
+ border-radius: 16px;
+ }
+ }
+
.avatar-wrapper {
display: flex;
align-items: center;
--
Gitblit v1.9.3